src/siri/grammar \
src/siri/help \
src/siri/net \
-src/siri/parser \
src/slist \
src/strextra \
src/test \
../src/siri/db/groups.c \
../src/siri/db/initsync.c \
../src/siri/db/insert.c \
+../src/siri/db/listener.c \
../src/siri/db/lookup.c \
../src/siri/db/median.c \
../src/siri/db/misc.c \
../src/siri/db/pools.c \
../src/siri/db/presuf.c \
../src/siri/db/props.c \
+../src/siri/db/queries.c \
../src/siri/db/query.c \
../src/siri/db/re.c \
../src/siri/db/reindex.c \
./src/siri/db/groups.o \
./src/siri/db/initsync.o \
./src/siri/db/insert.o \
+./src/siri/db/listener.o \
./src/siri/db/lookup.o \
./src/siri/db/median.o \
./src/siri/db/misc.o \
./src/siri/db/pools.o \
./src/siri/db/presuf.o \
./src/siri/db/props.o \
+./src/siri/db/queries.o \
./src/siri/db/query.o \
./src/siri/db/re.o \
./src/siri/db/reindex.o \
./src/siri/db/groups.d \
./src/siri/db/initsync.d \
./src/siri/db/insert.d \
+./src/siri/db/listener.d \
./src/siri/db/lookup.d \
./src/siri/db/median.d \
./src/siri/db/misc.d \
./src/siri/db/pools.d \
./src/siri/db/presuf.d \
./src/siri/db/props.d \
+./src/siri/db/queries.d \
./src/siri/db/query.d \
./src/siri/db/re.d \
./src/siri/db/reindex.d \
../src/siri/net/promise.c \
../src/siri/net/promises.c \
../src/siri/net/protocol.c \
-../src/siri/net/socket.c \
+../src/siri/net/stream.c \
+../src/siri/net/tcp.c \
../src/siri/net/pipe.c
OBJS += \
./src/siri/net/promise.o \
./src/siri/net/promises.o \
./src/siri/net/protocol.o \
-./src/siri/net/socket.o \
+./src/siri/net/stream.o \
+./src/siri/net/tcp.o \
./src/siri/net/pipe.o
C_DEPS += \
./src/siri/net/promise.d \
./src/siri/net/promises.d \
./src/siri/net/protocol.d \
-./src/siri/net/socket.d \
+./src/siri/net/stream.d \
+./src/siri/net/tcp.d \
./src/siri/net/pipe.d
+++ /dev/null
-################################################################################
-# Automatically-generated file. Do not edit!
-################################################################################
-
-# Add inputs and outputs from these tool invocations to the build variables
-C_SRCS += \
-../src/siri/parser/listener.c \
-../src/siri/parser/queries.c
-
-OBJS += \
-./src/siri/parser/listener.o \
-./src/siri/parser/queries.o
-
-C_DEPS += \
-./src/siri/parser/listener.d \
-./src/siri/parser/queries.d
-
-
-# Each subdirectory must supply rules for building sources it contributes
-src/siri/parser/%.o: ../src/siri/parser/%.c
- @echo 'Building file: $<'
- @echo 'Invoking: GCC C Compiler'
- gcc -DDEBUG=1 -I../include -O0 -g3 -Wall -Wextra $(CPPFLAGS) $(CFLAGS) -c -fmessage-length=0 -MMD -MP -MF"$(@:%.o=%.d)" -MT"$(@)" -o "$@" "$<"
- @echo 'Finished building: $<'
- @echo ' '
-
-
src/siri/grammar \
src/siri/help \
src/siri/net \
-src/siri/parser \
src/slist \
src/strextra \
src/test \
../src/siri/db/groups.c \
../src/siri/db/initsync.c \
../src/siri/db/insert.c \
+../src/siri/db/listener.c \
../src/siri/db/lookup.c \
../src/siri/db/median.c \
../src/siri/db/misc.c \
../src/siri/db/pools.c \
../src/siri/db/presuf.c \
../src/siri/db/props.c \
+../src/siri/db/queries.c \
../src/siri/db/query.c \
../src/siri/db/re.c \
../src/siri/db/reindex.c \
./src/siri/db/groups.o \
./src/siri/db/initsync.o \
./src/siri/db/insert.o \
+./src/siri/db/listener.o \
./src/siri/db/lookup.o \
./src/siri/db/median.o \
./src/siri/db/misc.o \
./src/siri/db/pools.o \
./src/siri/db/presuf.o \
./src/siri/db/props.o \
+./src/siri/db/queries.o \
./src/siri/db/query.o \
./src/siri/db/re.o \
./src/siri/db/reindex.o \
./src/siri/db/groups.d \
./src/siri/db/initsync.d \
./src/siri/db/insert.d \
+./src/siri/db/listener.d \
./src/siri/db/lookup.d \
./src/siri/db/median.d \
./src/siri/db/misc.d \
./src/siri/db/pools.d \
./src/siri/db/presuf.d \
./src/siri/db/props.d \
+./src/siri/db/queries.d \
./src/siri/db/query.d \
./src/siri/db/re.d \
./src/siri/db/reindex.d \
../src/siri/net/promise.c \
../src/siri/net/promises.c \
../src/siri/net/protocol.c \
-../src/siri/net/socket.c \
+../src/siri/net/stream.c \
+../src/siri/net/tcp.c \
../src/siri/net/pipe.c
OBJS += \
./src/siri/net/promise.o \
./src/siri/net/promises.o \
./src/siri/net/protocol.o \
-./src/siri/net/socket.o \
+./src/siri/net/stream.o \
+./src/siri/net/tcp.o \
./src/siri/net/pipe.o
C_DEPS += \
./src/siri/net/promise.d \
./src/siri/net/promises.d \
./src/siri/net/protocol.d \
-./src/siri/net/socket.d \
+./src/siri/net/stream.d \
+./src/siri/net/tcp.d \
./src/siri/net/pipe.d
+++ /dev/null
-################################################################################
-# Automatically-generated file. Do not edit!
-################################################################################
-
-# Add inputs and outputs from these tool invocations to the build variables
-C_SRCS += \
-../src/siri/parser/listener.c \
-../src/siri/parser/queries.c
-
-OBJS += \
-./src/siri/parser/listener.o \
-./src/siri/parser/queries.o
-
-C_DEPS += \
-./src/siri/parser/listener.d \
-./src/siri/parser/queries.d
-
-
-# Each subdirectory must supply rules for building sources it contributes
-src/siri/parser/%.o: ../src/siri/parser/%.c
- @echo 'Building file: $<'
- @echo 'Invoking: GCC C Compiler'
- gcc -I../include -O3 -Wall -Wextra $(CPPFLAGS) $(CFLAGS) -c -fmessage-length=0 -MMD -MP -MF"$(@:%.o=%.d)" -MT"$(@)" -o "$@" "$<"
- @echo 'Finished building: $<'
- @echo ' '
-
-
* - initial version, 08-03-2016
*
*/
-#pragma once
-#include <inttypes.h>
+#ifndef ARGPARSE_H_
+#define ARGPARSE_H_
#define ARGPARSE_SUCCESS 0
#define ARGPARSE_ERR_MISSING_VALUE -1
ARGPARSE_STORE_STR_CHOICE
} argparse_action_t;
-typedef struct
+typedef struct argparse_args_s argparse_args_t;
+typedef struct argparse_parser_s argparse_parser_t;
+typedef struct argparse_argument_s argparse_argument_t;
+
+#include <inttypes.h>
+
+void argparse_init(argparse_parser_t * parser);
+void argparse_free(argparse_parser_t * parser);
+void argparse_add_argument(
+ argparse_parser_t * parser,
+ argparse_argument_t * argument);
+void argparse_parse(argparse_parser_t *parser, int argc, char *argv[]);
+
+struct argparse_argument_s
{
char * name;
char shortcut;
char * str_default;
char * str_value;
char * choices; /* choices must be separated by commas */
-} argparse_argument_t;
+};
-typedef struct argparse_args_s
+struct argparse_args_s
{
argparse_argument_t * argument;
- struct argparse_args_s * next;
-} argparse_args_t;
+ argparse_args_t * next;
+};
-typedef struct argparse_parser_s
+struct argparse_parser_s
{
argparse_args_t * args;
int32_t show_help;
argparse_argument_t help;
-} argparse_parser_t;
+};
-void argparse_init(argparse_parser_t * parser);
-void argparse_free(argparse_parser_t * parser);
-void argparse_add_argument(
- argparse_parser_t * parser,
- argparse_argument_t * argument);
-void argparse_parse(argparse_parser_t *parser, int argc, char *argv[]);
+#endif /* ARGPARSE_H_ */
* - initial version, 13-06-2016
*
*/
-#pragma once
-#include <inttypes.h>
-#include <qpack/qpack.h>
-#include <cleri/cleri.h>
+#ifndef CEXPR_H_
+#define CEXPR_H_
#define CEXPR_MAX_CURLY_DEPTH 6
-typedef enum cexpr_operator
+typedef enum
{
CEXPR_EQ, /* equal */
CEXPR_NE, /* not equal */
CEXPR_OR,
} cexpr_operator_t;
-typedef struct cexpr_condition_s
-{
- uint32_t prop;
- cexpr_operator_t operator;
- int64_t int64;
- char * str;
-} cexpr_condition_t;
-
-typedef int (*cexpr_cb_t)(void * obj, cexpr_condition_t * cond);
-typedef int (*cexpr_cb_prop_t)(uint32_t prop);
-
+typedef union cexpr_via_u cexpr_via_t;
+typedef struct cexpr_condition_s cexpr_condition_t;
typedef struct cexpr_s cexpr_t;
+typedef struct cexpr_list_s cexpr_list_t;
-typedef struct cexpr_list_s
-{
- size_t len;
- cexpr_t * cexpr[CEXPR_MAX_CURLY_DEPTH];
-} cexpr_list_t;
-
-typedef union cexpr_via_u
-{
- cexpr_condition_t * cond;
- cexpr_t * cexpr;
-} cexpr_via_t;
+#include <inttypes.h>
+#include <qpack/qpack.h>
+#include <cleri/cleri.h>
-typedef struct cexpr_s
-{
- cexpr_operator_t operator; /* AND/OR */
- int8_t tp_a;
- int8_t tp_b;
- cexpr_via_t via_a;
- cexpr_via_t via_b;
-} cexpr_t;
+typedef int (*cexpr_cb_t)(void * obj, cexpr_condition_t * cond);
+typedef int (*cexpr_cb_prop_t)(uint32_t prop);
cexpr_t * cexpr_from_node(cleri_node_t * node);
int cexpr_int_cmp(
int cexpr_contains(cexpr_t * cexpr, cexpr_cb_prop_t cb);
void cexpr_free(cexpr_t * cexpr);
cexpr_operator_t cexpr_operator_fn(cleri_node_t * node);
+
+union cexpr_via_u
+{
+ cexpr_condition_t * cond;
+ cexpr_t * cexpr;
+};
+
+struct cexpr_condition_s
+{
+ uint32_t prop;
+ cexpr_operator_t operator;
+ int64_t int64;
+ char * str;
+};
+
+struct cexpr_list_s
+{
+ size_t len;
+ cexpr_t * cexpr[CEXPR_MAX_CURLY_DEPTH];
+};
+
+struct cexpr_s
+{
+ cexpr_operator_t operator; /* AND/OR */
+ int8_t tp_a;
+ int8_t tp_b;
+ cexpr_via_t via_a;
+ cexpr_via_t via_b;
+};
+
+#endif /* CEXPR_H_ */
* - initial version, 08-03-2016
*
*/
-#pragma once
+#ifndef CFGPARSER_H_
+#define CFGPARSER_H_
-#include <inttypes.h>
-
-typedef enum {
+typedef enum
+{
CFGPARSER_SUCCESS,
CFGPARSER_ERR_READING_FILE,
CFGPARSER_ERR_SESSION_NOT_OPEN,
CFGPARSER_ERR_OPTION_NOT_FOUND
} cfgparser_return_t;
-
-typedef enum {
+typedef enum
+{
CFGPARSER_TP_INTEGER,
CFGPARSER_TP_STRING,
CFGPARSER_TP_REAL,
} cfgparser_tp_t;
-typedef union
-{
- int32_t integer;
- double real;
- char * string;
-} cfgparser_u;
-
-typedef struct cfgparser_option_s
-{
- char * name;
- cfgparser_tp_t tp;
- cfgparser_u * val;
- cfgparser_u * def;
- struct cfgparser_option_s * next;
-} cfgparser_option_t;
-
-typedef struct cfgparser_section_s
-{
- char * name;
- cfgparser_option_t * options;
- struct cfgparser_section_s * next;
-} cfgparser_section_t;
-
-typedef struct cfgparser_s
-{
- cfgparser_section_t * sections;
-} cfgparser_t;
+typedef union cfgparser_u cfgparser_via_t;
+typedef struct cfgparser_option_s cfgparser_option_t;
+typedef struct cfgparser_section_s cfgparser_section_t;
+typedef struct cfgparser_s cfgparser_t;
+#include <inttypes.h>
cfgparser_return_t cfgparser_read(cfgparser_t * cfgparser, const char * fn);
-
cfgparser_t * cfgparser_new(void);
-
void cfgparser_free(cfgparser_t * cfgparser);
-
cfgparser_section_t * cfgparser_section(
cfgparser_t * cfgparser,
const char * name);
-
cfgparser_option_t * cfgparser_string_option(
cfgparser_section_t * section,
const char * name,
const char * val,
const char * def);
-
cfgparser_option_t * cfgparser_integer_option(
cfgparser_section_t * section,
const char * name,
int32_t val,
int32_t def);
-
cfgparser_option_t * cfgparser_real_option(
cfgparser_section_t * section,
const char * name,
double val,
double def);
-
const char * cfgparser_errmsg(cfgparser_return_t err);
-
cfgparser_return_t cfgparser_get_section(
cfgparser_section_t ** section,
cfgparser_t * cfgparser,
const char * section_name);
-
cfgparser_return_t cfgparser_get_option(
cfgparser_option_t ** option,
cfgparser_t * cfgparser,
const char * section_name,
const char * option_name);
+
+union cfgparser_u
+{
+ int32_t integer;
+ double real;
+ char * string;
+};
+
+struct cfgparser_option_s
+{
+ char * name;
+ cfgparser_tp_t tp;
+ cfgparser_via_t * val;
+ cfgparser_via_t * def;
+ struct cfgparser_option_s * next;
+};
+
+struct cfgparser_section_s
+{
+ char * name;
+ cfgparser_option_t * options;
+ struct cfgparser_section_s * next;
+};
+
+struct cfgparser_s
+{
+ cfgparser_section_t * sections;
+};
+
+#endif /* CFGPARSER_H_ */
* - initial version, 18-03-2016
*
*/
-#pragma once
-
-#include <inttypes.h>
-#include <stddef.h>
-#include <stdio.h>
+#ifndef CTREE_H_
+#define CTREE_H_
enum
{
typedef struct ct_node_s ct_node_t;
typedef struct ct_node_s * ct_nodes_t[32];
+#include <inttypes.h>
+#include <stddef.h>
+#include <stdio.h>
+
+typedef int (*ct_item_cb)(
+ const char * key,
+ size_t len,
+ void * data,
+ void * args);
+typedef int (*ct_val_cb)(void * data, void * args);
+typedef void (*ct_free_cb)(void * data);
+
+ct_t * ct_new(void);
+void ct_free(ct_t * ct, ct_free_cb cb);
+int ct_add(ct_t * ct, const char * key, void * data);
+void * ct_get(ct_t * node, const char * key);
+void ** ct_getaddr(ct_t * ct, const char * key);
+void * ct_getn(ct_t * ct, const char * key, size_t n);
+void * ct_pop(ct_t * ct, const char * key);
+int ct_items(ct_t * ct, ct_item_cb cb, void * args);
+int ct_values(ct_t * ct, ct_val_cb cb, void * args);
+void ct_valuesn(ct_t * ct, size_t * n, ct_val_cb cb, void * args);
+
struct ct_node_s
{
uint8_t offset;
ct_nodes_t * nodes;
};
-typedef int (*ct_item_cb)(
- const char * key,
- size_t len,
- void * data,
- void * args);
-typedef int (*ct_val_cb)(void * data, void * args);
-typedef void (*ct_free_cb)(void * data);
-
-ct_t * ct_new(void);
-void ct_free(ct_t * ct, ct_free_cb cb);
-int ct_add(ct_t * ct, const char * key, void * data);
-void * ct_get(ct_t * node, const char * key);
-void ** ct_getaddr(ct_t * ct, const char * key);
-void * ct_getn(ct_t * ct, const char * key, size_t n);
-void * ct_pop(ct_t * ct, const char * key);
-int ct_items(ct_t * ct, ct_item_cb cb, void * args);
-int ct_values(ct_t * ct, ct_val_cb cb, void * args);
-void ct_valuesn(ct_t * ct, size_t * n, ct_val_cb cb, void * args);
-
+#endif /* CTREE_H_ */
* - initial version, 19-04-2016
*
*/
-#pragma once
-
-#include <inttypes.h>
+#ifndef EXPR_H_
+#define EXPR_H_
#define EXPR_DIVISION_BY_ZERO -1
#define EXPR_MODULO_BY_ZERO -2
*/
#define EXPR_MAX_SIZE 512
+#include <inttypes.h>
+
/* Returns 0 when result is successful set */
int expr_parse(int64_t * result, const char * expr);
+
+
+#endif /* EXPR_H_ */
* - initial version, 03-08-2016
*
*/
-#pragma once
+#ifndef IMAP_H_
+#define IMAP_H_
+
+typedef struct imap_node_s imap_node_t;
+typedef struct imap_s imap_t;
#include <inttypes.h>
#include <stddef.h>
#include <slist/slist.h>
-typedef struct imap_node_s imap_node_t;
-typedef struct imap_s imap_t;
-
typedef int (*imap_cb)(void * data, void * args);
typedef int (*imap_free_cb)(void * data);
imap_t * imap,
imap_free_cb decref_cb);
-struct imap_node_s
-{
- size_t size;
- void * data ;
- imap_node_t * nodes;
-};
-
-struct imap_s
-{
- size_t len;
- slist_t * slist;
- imap_node_t nodes[];
-};
-
imap_t * imap_new(void);
void imap_free(imap_t * imap, imap_free_cb cb);
int imap_set(imap_t * imap, uint64_t id, void * data);
imap_t * dest,
imap_t * imap,
imap_free_cb decref_cb);
+
+
+struct imap_node_s
+{
+ size_t size;
+ void * data ;
+ imap_node_t * nodes;
+};
+
+struct imap_s
+{
+ size_t len;
+ slist_t * slist;
+ imap_node_t nodes[];
+};
+
+#endif /* IMAP_H_ */
* - initial version, 21-04-2016
*
*/
-#pragma once
+#ifndef ISO8601_H_
+#define ISO8601_H_
#include <inttypes.h>
* in the string.
*/
int64_t iso8601_parse_date(const char * str, iso8601_tz_t tz);
+
+#endif /* ISO8601_H_ */
* - initial version, 03-05-2016
*
*/
-#pragma once
+#ifndef LLIST_H_
+#define LLIST_H_
typedef struct llist_s llist_t;
typedef struct llist_node_s llist_node_t;
#include <stdio.h>
#include <slist/slist.h>
+typedef int (*llist_cb)(void * data, void * args);
+
+llist_t * llist_new(void);
+void llist_free_cb(llist_t * llist, llist_cb cb, void * args);
+int llist_append(llist_t * llist, void * data);
+int llist_walk(llist_t * llist, llist_cb cb, void * args);
+void llist_walkn(llist_t * llist, size_t * n, llist_cb cb, void * args);
+slist_t * llist2slist(llist_t * llist);
+void * llist_get(llist_t * llist, llist_cb cb, void * args);
+void * llist_remove(llist_t * llist, llist_cb cb, void * args);
+void * llist_pop(llist_t * llist);
+void * llist_shift(llist_t * llist);
+
struct llist_node_s
{
void * data;
llist_node_t * last;
};
-typedef int (*llist_cb)(void * data, void * args);
-
-llist_t * llist_new(void);
-void llist_free_cb(llist_t * llist, llist_cb cb, void * args);
-int llist_append(llist_t * llist, void * data);
-int llist_walk(llist_t * llist, llist_cb cb, void * args);
-void llist_walkn(llist_t * llist, size_t * n, llist_cb cb, void * args);
-slist_t * llist2slist(llist_t * llist);
-void * llist_get(llist_t * llist, llist_cb cb, void * args);
-void * llist_remove(llist_t * llist, llist_cb cb, void * args);
-void * llist_pop(llist_t * llist);
-void * llist_shift(llist_t * llist);
+#endif /* LLIST_H_ */
* - initial version, 13-07-2016
*
*/
-#pragma once
+#ifndef LOCK_H_
+#define LOCK_H_
#define LOCK_QUIT_IF_EXIST 1
lock_t lock_lock(const char * path, int flags);
lock_t lock_unlock(const char * path);
const char * lock_str(lock_t rc);
+
+#endif /* LOCK_H_ */
* - initial version, 08-03-2016
*
*/
-#pragma once
+#ifndef LOGGER_H_
+#define LOGGER_H_
#ifdef __APPLE__
#define _LOGGER_IO_FILE __sFILE
#else
+#include <stdio.h>
#define _LOGGER_IO_FILE _IO_FILE
#endif
#define LOGGER_FLAG_COLORED 1
-typedef struct logger_s
-{
- struct _LOGGER_IO_FILE * ostream;
- int level;
- const char * level_name;
- int flags;
-} logger_t;
+typedef struct logger_s logger_t;
const char * LOGGER_LEVEL_NAMES[LOGGER_NUM_LEVELS];
fprintf(Logger.ostream, "%s:%d ", __FILE__, __LINE__); \
log_critical(fmt, ##__VA_ARGS__)
+struct logger_s
+{
+ struct _LOGGER_IO_FILE * ostream;
+ int level;
+ const char * level_name;
+ int flags;
+};
+
+#endif /* LOGGER_H_ */
* - initial version, 13-03-2016
*
*/
+#ifndef MOTD_H_
+#define MOTD_H_
const char * motd_get_random_msg(void);
+
+#endif /* MOTD_H_ */
* - initial version, 24-02-2017
*
*/
-#pragma once
+#ifndef OWCRYPT_H_
+#define OWCRYPT_H_
#define OWCRYPT_SZ 64
#define OWCRYPT_SALT_SZ 10
void owcrypt(const char * password, const char * salt, char * encrypted);
void owcrypt_gen_salt(char * salt);
+
+#endif /* OWCRYPT_H_ */
*
*/
+#ifndef PROCINFO_H_
+#define PROCINFO_H_
/* Total_Physical_Memory returned in KB */
long int procinfo_total_physical_memory(void);
/* Total Open Files */
long int procinfo_open_files(const char * path);
+
+
+#endif /* PROCINFO_H_ */
* - initial version, 11-03-2016
*
*/
-#pragma once
+#ifndef QPACK_H_
+#define QPACK_H_
#include <inttypes.h>
#include <stdlib.h>
QP_MAP_CLOSE, /* close map */
} qp_types_t;
-typedef union qp_via_u
+typedef union qp_via_u qp_via_t;
+typedef struct qp_obj_s qp_obj_t;
+typedef struct qp_unpacker_s qp_unpacker_t;
+typedef struct qp_packer_s qp_packer_t;
+typedef FILE qp_fpacker_t;
+
+union qp_via_u
{
int64_t int64;
uint64_t uint64;
double real;
unsigned char * raw;
char * str;
-} qp_via_t;
+};
-typedef struct qp_obj_s
+struct qp_obj_s
{
uint8_t tp;
size_t len;
qp_via_t via;
-} qp_obj_t;
+};
-typedef struct qp_unpacker_s
+struct qp_unpacker_s
{
unsigned char * source; /* can be NULL or a copy or the source */
unsigned char * pt;
unsigned char * end;
-} qp_unpacker_t;
+};
-typedef struct qp_packer_s
+struct qp_packer_s
{
size_t len;
size_t buffer_size;
size_t alloc_size;
unsigned char * buffer;
-} qp_packer_t;
+};
+
-typedef FILE qp_fpacker_t;
#define qp_open fopen /* returns NULL in case of an error */
#define qp_close fclose /* 0 if successful, EOF in case of an error */
#define qp_flush fflush /* 0 if successful, EOF in case of an error */
BUF__[0] = QP_INT16; \
memcpy(&BUF__[1], &N__, 2);
-
+#endif /* QPACK_H_ */
* - initial version, 16-03-2017
*
*/
-#pragma once
-#include <qpack/qpack.h>
-#include <siri/siri.h>
+#ifndef SIRI_ADMIN_ACCOUNT_H_
+#define SIRI_ADMIN_ACCOUNT_H_
-typedef struct siri_s siri_t;
+typedef struct siri_admin_account_s siri_admin_account_t;
-typedef struct siri_admin_account_s
-{
- char * account;
- char * password; /* keeps an encrypted password */
-} siri_admin_account_t;
+#include <qpack/qpack.h>
+#include <siri/siri.h>
int siri_admin_account_init(siri_t * siri);
void siri_admin_account_destroy(siri_t * siri);
qp_obj_t * qp_account,
char * err_msg);
int siri_admin_account_save(siri_t * siri, char * err_msg);
+
+struct siri_admin_account_s
+{
+ char * account;
+ char * password; /* keeps an encrypted password */
+};
+
+#endif /* SIRI_ADMIN_ACCOUNT_H_ */
* - initial version, 24-03-2017
*
*/
-#pragma once
+#ifndef SIRI_ADMIN_CLIENT_H_
+#define SIRI_ADMIN_CLIENT_H_
+
+typedef struct siri_admin_client_s siri_admin_client_t;
#include <inttypes.h>
#include <uv.h>
#include <qpack/qpack.h>
-#include <siri/net/pkg.h>
#include <uuid/uuid.h>
+#include <siri/net/pkg.h>
+
+int siri_admin_client_request(
+ uint16_t pid,
+ uint16_t port,
+ int pool,
+ uuid_t * uuid,
+ qp_obj_t * host,
+ qp_obj_t * username,
+ qp_obj_t * password,
+ qp_obj_t * dbname,
+ const char * dbpath,
+ sirinet_stream_t * client,
+ char * err_msg);
-typedef struct siri_admin_client_s
+void siri_admin_client_free(siri_admin_client_t * adm_client);
+
+struct siri_admin_client_s
{
uint8_t request;
uint8_t flags;
char * password;
char * dbname;
char * dbpath;
- uv_stream_t * client;
+ sirinet_stream_t * client;
sirinet_pkg_t * pkg;
-} siri_admin_client_t;
+};
-int siri_admin_client_request(
- uint16_t pid,
- uint16_t port,
- int pool,
- uuid_t * uuid,
- qp_obj_t * host,
- qp_obj_t * username,
- qp_obj_t * password,
- qp_obj_t * dbname,
- const char * dbpath,
- uv_stream_t * client,
- char * err_msg);
-
-void siri_admin_client_free(siri_admin_client_t * adm_client);
+#endif /* SIRI_ADMIN_CLIENT_H_ */
* - initial version, 16-03-2017
*
*/
-#pragma once
-#include <qpack/qpack.h>
-#include <siri/net/protocol.h>
+#ifndef SIRI_ADMIN_REQUEST_H_
+#define SIRI_ADMIN_REQUEST_H_
typedef enum
{
ADMIN_GET_DATABASES
} admin_request_t;
+#include <qpack/qpack.h>
+#include <siri/net/protocol.h>
+
int siri_admin_request_init(void);
void siri_admin_request_destroy(void);
cproto_server_t siri_admin_request(
qp_obj_t * qp_account,
qp_packer_t ** packaddr,
uint16_t pid,
- uv_stream_t * client,
+ sirinet_stream_t * client,
char * err_msg);
void siri_admin_request_rollback(const char * dbpath);
+
+
+#endif /* SIRI_ADMIN_REQUEST_H_ */
-#pragma once
+/*
+ * args.h - SiriDB Arguments.
+ *
+ * author : Jeroen van der Heijden
+ * email : jeroen@transceptor.technology
+ * copyright : 2017, Transceptor Technology
+ *
+ * changes
+ * - initial version, 16-03-2017
+ */
+#ifndef SIRI_ARGS_H_
+#define SIRI_ARGS_H_
+
+typedef struct siri_args_s siri_args_t;
#include <inttypes.h>
#include <argparse/argparse.h>
#include <siri/siri.h>
-typedef struct siri_s siri_t;
+/* arguments are configured and parsed here */
+void siri_args_parse(siri_t * siri, int argc, char *argv[]);
-typedef struct siri_args_s
+struct siri_args_s
{
/* true/false props */
int32_t version;
/* string props */
char config[ARGPARSE_MAX_LEN_ARG];
char log_level[ARGPARSE_MAX_LEN_ARG];
-} siri_args_t;
+};
-/* arguments are configured and parsed here */
-void siri_args_parse(siri_t * siri, int argc, char *argv[]);
+#endif /* SIRI_ARGS_H_ */
* - initial version, 21-07-2016
*
*/
-#pragma once
+#ifndef SIRI_ASYC_H_
+#define SIRI_ASYC_H_
+
+typedef struct siri_async_s siri_async_t;
#include <uv.h>
#include <inttypes.h>
-typedef struct siri_async_s
-{
- uv_close_cb free_cb;
- uint8_t ref;
-} siri_async_t;
-
void siri_async_close(uv_handle_t * handle);
void siri_async_decref(uv_async_t ** handle);
#define siri_async_incref(HANDLE__) ((siri_async_t *) HANDLE__->data)->ref++
+
+struct siri_async_s
+{
+ uv_close_cb free_cb;
+ uint8_t ref;
+};
+
+#endif /* SIRI_ASYC_H_ */
* - initial version, 27-09-2016
*
*/
-#pragma once
+#ifndef SIRI_BACKUP_H_
+#define SIRI_BACKUP_H_
#include <siri/siri.h>
#include <siri/db/db.h>
-typedef struct siri_s siri_t;
-typedef struct siridb_s siridb_t;
-
int siri_backup_init(siri_t * siri);
void siri_backup_destroy(siri_t * siri);
int siri_backup_enable(siri_t * siri, siridb_t * siridb);
int siri_backup_disable(siri_t * siri, siridb_t * siridb);
+
+
+#endif /* SIRI_BACKUP_H_ */
-#pragma once
+/*
+ * cfg.h - SiriDB Config.
+ *
+ * author : Jeroen van der Heijden
+ * email : jeroen@transceptor.technology
+ * copyright : 2017, Transceptor Technology
+ *
+ * changes
+ * - initial version, 16-03-2017
+ */
+#ifndef SIRI_CFG_H_
+#define SIRI_CFG_H_
+
+typedef struct siri_cfg_s siri_cfg_t;
+
+#define SIRI_CFG_MAX_LEN_ADDRESS 256
#include <inttypes.h>
#include <limits.h>
#include <siri/siri.h>
#include <xpath/xpath.h>
+void siri_cfg_init(siri_t * siri);
+void siri_cfg_destroy(siri_t * siri);
-typedef struct siri_s siri_t;
-
-#define SIRI_CFG_MAX_LEN_ADDRESS 256
-
-typedef struct siri_cfg_s
+struct siri_cfg_s
{
uint16_t listen_client_port;
uint16_t listen_backend_port;
char default_db_path[SIRI_PATH_MAX];
uint8_t pipe_support;
char pipe_client_name[SIRI_PATH_MAX];
-} siri_cfg_t;
+};
-void siri_cfg_init(siri_t * siri);
-void siri_cfg_destroy(siri_t * siri);
+#endif /* SIRI_CFG_H_ */
* - initial version, 13-03-2016
*
*/
-#pragma once
-
-#include <cleri/cleri.h>
-
+#ifndef SIRIDB_ACCESS_H_
+#define SIRIDB_ACCESS_H_
+/* definitions of all access rights */
#define SIRIDB_ACCESS_SHOW 1
#define SIRIDB_ACCESS_COUNT 2
#define SIRIDB_ACCESS_LIST 4
/* this is a save size since access string cannot contain double items */
#define SIRIDB_ACCESS_STR_MAX 128
+/* profile definitions */
#define SIRIDB_ACCESS_PROFILE_READ \
SIRIDB_ACCESS_SHOW | \
SIRIDB_ACCESS_COUNT | \
SIRIDB_ACCESS_GRANT | \
SIRIDB_ACCESS_REVOKE
+typedef struct siridb_access_repr_s siridb_access_repr_t;
-typedef struct siridb_access_repr_s
-{
- const char * repr;
- uint32_t access_bit;
-} siridb_access_repr_t;
-
+#include <cleri/cleri.h>
uint32_t siridb_access_from_strn(const char * str, size_t n);
void siridb_access_to_str(char * str, uint32_t access_bit);
+struct siridb_access_repr_s
+{
+ const char * repr;
+ uint32_t access_bit;
+};
+
+#endif /* SIRIDB_ACCESS_H_ */
* - initial version, 15-04-2016
*
*/
-#pragma once
+#ifndef SIRIDB_AGGREGATE_H_
+#define SIRIDB_AGGREGATE_H_
+
+typedef struct siridb_aggr_s siridb_aggr_t;
#include <siri/db/points.h>
#include <siri/grammar/gramp.h>
#include <qpack/qpack.h>
#include <pcre2.h>
-typedef struct siridb_point_s siridb_point_t;
-typedef struct siridb_points_s siridb_points_t;
+siridb_points_t * siridb_aggregate_run(
+ siridb_points_t * source,
+ siridb_aggr_t * aggr,
+ char * err_msg);
+void siridb_init_aggregates(void);
+slist_t * siridb_aggregate_list(cleri_children_t * children, char * err_msg);
+void siridb_aggregate_list_free(slist_t * alist);
+int siridb_aggregate_can_skip(cleri_children_t * children);
-typedef struct siridb_aggr_s
+struct siridb_aggr_s
{
uint32_t gid;
cexpr_operator_t filter_opr;
pcre2_code * regex; \
pcre2_match_data * match_data;
qp_via_t filter_via;
-} siridb_aggr_t;
+};
-siridb_points_t * siridb_aggregate_run(
- siridb_points_t * source,
- siridb_aggr_t * aggr,
- char * err_msg);
-
-void siridb_init_aggregates(void);
-slist_t * siridb_aggregate_list(cleri_children_t * children, char * err_msg);
-void siridb_aggregate_list_free(slist_t * alist);
-int siridb_aggregate_can_skip(cleri_children_t * children);
+#endif /* SIRIDB_AGGREGATE_H_ */
* - initial version, 10-03-2016
*
*/
-#pragma once
+#ifndef SIRIDB_AUTH_H_
+#define SIRIDB_AUTH_H_
#include <stddef.h>
#include <siri/net/clserver.h>
#include <siri/net/protocol.h>
cproto_server_t siridb_auth_user_request(
- uv_stream_t * client,
+ sirinet_stream_t * client,
qp_obj_t * qp_username,
qp_obj_t * qp_password,
qp_obj_t * qp_dbname);
bproto_server_t siridb_auth_server_request(
- uv_stream_t * client,
+ sirinet_stream_t * client,
qp_obj_t * qp_uuid,
qp_obj_t * qp_dbname,
qp_obj_t * qp_version,
qp_obj_t * qp_min_version);
+
+#endif /* SIRIDB_AUTH_H_ */
* - initial version, 01-04-2016
*
*/
-#pragma once
+#ifndef SIRIDB_BUFFER_H_
+#define SIRIDB_BUFFER_H_
#include <siri/db/db.h>
#include <siri/db/series.h>
#define MAX_BUFFER_SZ 10485760
-typedef struct siridb_s siridb_t;
-typedef struct siridb_series_s siridb_series_t;
-typedef struct siridb_points_s siridb_points_t;
-
int siridb_buffer_new_series(
siridb_t * siridb,
siridb_series_t * series);
siridb_series_t * series,
uint64_t * ts,
qp_via_t * val);
+
+#endif /* SIRIDB_BUFFER_H_ */
+++ /dev/null
-/*
- * content.h - Log data (string content)
- *
- * author : Jeroen van der Heijden
- * email : jeroen@transceptor.technology
- * copyright : 2017, Transceptor Technology
- *
- * changes
- * - initial version, 11-12-2017
- *
- */
-#pragma once
-
-
-typedef struct siridb_content_s
-{
- size_t size;
- char * data;
-} siridb_content_t;
-
* - initial version, 10-03-2016
*
*/
-#pragma once
+#ifndef SIRIDB_H_
+#define SIRIDB_H_
-#include <siri/err.h>
-#include <siri/db/time.h>
-#include <siri/db/user.h>
+typedef struct siridb_s siridb_t;
+
+#define SIRIDB_MAX_SIZE_ERR_MSG 1024
+#define SIRIDB_MAX_DBNAME_LEN 256 /* 255 + NULL */
+#define SIRIDB_SCHEMA 3
+#define SIRIDB_FLAG_REINDEXING 1
+
+#define DEF_DROP_THRESHOLD 1.0 /* 100% */
+#define DEF_SELECT_POINTS_LIMIT 1000000 /* one million */
+#define DEF_LIST_LIMIT 10000 /* ten thousand */
+
+#include <string.h>
+#include <uv.h>
#include <qpack/qpack.h>
-#include <siri/db/server.h>
-#include <siri/db/pools.h>
#include <ctree/ctree.h>
#include <imap/imap.h>
#include <imap/imap.h>
#include <iso8601/iso8601.h>
#include <llist/llist.h>
-#include <string.h>
-#include <uv.h>
+#include <siri/err.h>
+#include <siri/db/time.h>
+#include <siri/db/user.h>
+#include <siri/db/server.h>
+#include <siri/db/pools.h>
#include <siri/db/fifo.h>
#include <siri/db/replicate.h>
#include <siri/db/reindex.h>
#include <siri/db/groups.h>
#include <siri/db/tasks.h>
+#include <siri/db/time.h>
-#define SIRIDB_MAX_SIZE_ERR_MSG 1024
-#define SIRIDB_MAX_DBNAME_LEN 256 /* 255 + NULL */
-#define SIRIDB_SCHEMA 3
-#define SIRIDB_FLAG_REINDEXING 1
-
-#define DEF_DROP_THRESHOLD 1.0 /* 100% */
-#define DEF_SELECT_POINTS_LIMIT 1000000 /* one million */
-#define DEF_LIST_LIMIT 10000 /* ten thousand */
-
-#define SIRIDB_GET_FN(FN, __path, FILENAME) \
- char FN[strlen(__path) + strlen(FILENAME) + 1]; \
- sprintf(FN, "%s%s", __path, FILENAME);
-
-/* Schema File Check
- * Needs fn and unpacker, free unpacker in case of an error.
- * Returns current function with -1 in case of an error and
- * raises a SIGNAL in case of a memory error.
- */
-#define siridb_schema_check(SCHEMA) \
- /* read and check schema */ \
- qp_obj_t qp_schema; \
- if (!qp_is_array(qp_next(unpacker, NULL)) || \
- qp_next(unpacker, &qp_schema) != QP_INT64 || \
- qp_schema.via.int64 != SCHEMA) \
- { \
- log_critical("Invalid schema detected in '%s'", fn); \
- qp_unpacker_ff_free(unpacker); \
- return -1; \
- }
+int32_t siridb_get_uptime(siridb_t * siridb);
+int8_t siridb_get_idle_percentage(siridb_t * siridb);
+int siridb_is_db_path(const char * dbpath);
+siridb_t * siridb_new(const char * dbpath, int lock_flags);
+siridb_t * siridb_get(llist_t * siridb_list, const char * dbname);
+void siridb_decref_cb(siridb_t * siridb, void * args);
+ssize_t siridb_get_file(char ** buffer, siridb_t * siridb);
+int siridb_open_files(siridb_t * siridb);
+int siridb_save(siridb_t * siridb);
+void siridb__free(siridb_t * siridb);
-typedef struct siridb_time_s siridb_time_t;
-typedef struct siridb_server_s siridb_server_t;
-typedef struct siridb_users_s siridb_users_t;
-typedef struct siridb_pools_s siridb_pools_t;
-typedef struct ct_node_s ct_node_t;
-typedef struct imap_s imap_t;
-typedef struct imap_s imap_t;
-typedef struct siridb_fifo_s siridb_fifo_t;
-typedef struct siridb_replicate_s siridb_replicate_t;
-typedef struct siridb_reindex_s siridb_reindex_t;
-typedef struct siridb_groups_s siridb_groups_t;
+#define siridb_incref(siridb) siridb->ref++
+#define siridb_decref(_siridb) if (!--_siridb->ref) siridb__free(_siridb)
+#define siridb_is_reindexing(siridb) (siridb->flags & SIRIDB_FLAG_REINDEXING)
-typedef struct siridb_s
+struct siridb_s
{
uint16_t ref;
uint8_t flags;
siridb_reindex_t * reindex;
siridb_groups_t * groups;
siridb_tasks_t tasks;
-} siridb_t;
-
-int32_t siridb_get_uptime(siridb_t * siridb);
-int8_t siridb_get_idle_percentage(siridb_t * siridb);
-int siridb_is_db_path(const char * dbpath);
-siridb_t * siridb_new(const char * dbpath, int lock_flags);
-siridb_t * siridb_get(llist_t * siridb_list, const char * dbname);
-void siridb_decref_cb(siridb_t * siridb, void * args);
-ssize_t siridb_get_file(char ** buffer, siridb_t * siridb);
-int siridb_open_files(siridb_t * siridb);
-int siridb_save(siridb_t * siridb);
-void siridb__free(siridb_t * siridb);
+};
-#define siridb_incref(siridb) siridb->ref++
-#define siridb_decref(_siridb) if (!--_siridb->ref) siridb__free(_siridb)
-
-#define siridb_is_reindexing(siridb) (siridb->flags & SIRIDB_FLAG_REINDEXING)
+#endif /* SIRIDB_H_ */
* - initial version, 30-06-2016
*
*/
-#pragma once
-#include <siri/net/pkg.h>
+#ifndef SIRIDB_FFILE_H_
+#define SIRIDB_FFILE_H_
typedef enum
{
FFILE_SUCCESS
} siridb_ffile_result_t;
-typedef struct siridb_ffile_s
-{
- uint64_t id;
- char * fn;
- uint32_t free_space;
- uint32_t next_size; /* must be uint32_t (4 bytes) */
- FILE * fp;
- int fd;
- long int size;
-} siridb_ffile_t;
+typedef struct siridb_ffile_s siridb_ffile_t;
+
+#include <siri/net/pkg.h>
void siridb_ffile_open(siridb_ffile_t * ffile, const char * opentype);
siridb_ffile_t * siridb_ffile_new(
siridb_ffile_result_t siridb_ffile_append(
siridb_ffile_t * ffile,
sirinet_pkg_t * pkg);
+
+struct siridb_ffile_s
+{
+ uint64_t id;
+ char * fn;
+ uint32_t free_space;
+ uint32_t next_size; /* must be uint32_t (4 bytes) */
+ FILE * fp;
+ int fd;
+ long int size;
+};
+
+#endif /* SIRIDB_FFILE_H_ */
* - initial version, 30-06-2016
*
*/
-#pragma once
+#ifndef SIRIDB_FIFO_H_
+#define SIRIDB_FIFO_H_
+
+typedef struct siridb_fifo_s siridb_fifo_t;
+
#include <stddef.h>
#include <siri/db/db.h>
#include <llist/llist.h>
#include <siri/db/ffile.h>
-typedef struct siridb_fifo_s
-{
- char * path;
- llist_t * fifos;
- siridb_ffile_t * in;
- siridb_ffile_t * out;
- ssize_t max_id; /* max_id can be -1 */
-} siridb_fifo_t;
-
siridb_fifo_t * siridb_fifo_new(siridb_t * siridb);
void siridb_fifo_free(siridb_fifo_t * fifo);
* Returns 1 if the fifo buffer is open or 0 if closed.
*/
#define siridb_fifo_is_open(fifo) (fifo->in->fp != NULL)
+
+struct siridb_fifo_s
+{
+ char * path;
+ llist_t * fifos;
+ siridb_ffile_t * in;
+ siridb_ffile_t * out;
+ ssize_t max_id; /* max_id can be -1 */
+};
+
+#endif /* SIRIDB_FIFO_H_ */
* - initial version, 31-07-2016
*
*/
-#pragma once
+#ifndef SIRIDB_FORWARD_H_
+#define SIRIDB_FORWARD_H_
+
+typedef struct siridb_forward_s siridb_forward_t;
-#include <siri/db/db.h>
#include <inttypes.h>
#include <uv.h>
+#include <siri/db/db.h>
-typedef struct siridb_s siridb_t;
+siridb_forward_t * siridb_forward_new(siridb_t * siridb);
+void siridb_forward_free(siridb_forward_t * forward);
+void siridb_forward_points_to_pools(uv_async_t * handle);
-typedef struct siridb_forward_s
+struct siridb_forward_s
{
uv_close_cb free_cb; /* must be on top */
uint8_t ref;
uint16_t size; /* number of packers (one for each pool - 1) */
siridb_t * siridb;
qp_packer_t * packer[];
-} siridb_forward_t;
-
+};
-siridb_forward_t * siridb_forward_new(siridb_t * siridb);
-void siridb_forward_free(siridb_forward_t * forward);
-void siridb_forward_points_to_pools(uv_async_t * handle);
+#endif /* SIRIDB_FORWARD_H_ */
* - initial version, 16-08-2016
*
*/
-#pragma once
+#ifndef SIRIDB_GROUP_H_
+#define SIRIDB_GROUP_H_
#define PCRE2_CODE_UNIT_WIDTH 8
-
-#include <slist/slist.h>
-#include <siri/db/series.h>
-#include <pcre2.h>
-
#define GROUP_FLAG_INIT 1
#define GROUP_FLAG_DROPPED 2
-typedef struct siridb_series_s siridb_series_t;
+typedef struct siridb_group_s siridb_group_t;
-typedef struct siridb_group_s
-{
- uint16_t ref;
- uint16_t flags;
- uint32_t n; /* total series (needs an update from all pools) */
- char * name;
- char * source; /* pattern/flags representation */
- slist_t * series;
- pcre2_code * regex;
- pcre2_match_data * match_data;
-} siridb_group_t;
+#include <slist/slist.h>
+#include <siri/db/series.h>
+#include <pcre2.h>
siridb_group_t * siridb_group_new(
const char * source,
#define siridb_group_incref(group) group->ref++
#define siridb_group_decref(group__) \
if (!--group__->ref) siridb__group_free(group__)
+
+struct siridb_group_s
+{
+ uint16_t ref;
+ uint16_t flags;
+ uint32_t n; /* total series (needs an update from all pools) */
+ char * name;
+ char * source; /* pattern/flags representation */
+ slist_t * series;
+ pcre2_code * regex;
+ pcre2_match_data * match_data;
+};
+
+#endif /* SIRIDB_GROUP_H_ */
* - initial version, 16-08-2016
*
*/
-#pragma once
-
-#include <ctree/ctree.h>
-#include <slist/slist.h>
-#include <uv.h>
-#include <siri/db/db.h>
-#include <siri/net/pkg.h>
+#ifndef SIRIDB_GROUPS_H_
+#define SIRIDB_GROUPS_H_
typedef enum
{
GROUPS_CLOSED
} siridb_groups_status_t;
+typedef struct siridb_groups_s siridb_groups_t;
#define GROUPS_FLAG_DROPPED_SERIES 1
-typedef struct siridb_groups_s
-{
- uint8_t status;
- uint8_t flags;
- uint8_t ref;
- char * fn;
- ct_t * groups;
- slist_t * nseries; /* list of series we need to assign to groups */
- slist_t * ngroups; /* list of groups which need initialization */
- uv_mutex_t mutex;
- uv_work_t work;
-} siridb_groups_t;
+#include <ctree/ctree.h>
+#include <slist/slist.h>
+#include <uv.h>
+#include <siri/db/db.h>
+#include <siri/net/pkg.h>
siridb_groups_t * siridb_groups_new(siridb_t * siridb);
void siridb_groups_start(siridb_groups_t * groups);
int siridb_groups_add_series(
siridb_groups_t * groups,
siridb_series_t * series);
+
+struct siridb_groups_s
+{
+ uint8_t status;
+ uint8_t flags;
+ uint8_t ref;
+ char * fn;
+ ct_t * groups;
+ slist_t * nseries; /* list of series we need to assign to groups */
+ slist_t * ngroups; /* list of groups which need initialization */
+ uv_mutex_t mutex;
+ uv_work_t work;
+};
+#endif /* SIRIDB_GROUPS_H_ */
* - initial version, 22-07-2016
*
*/
-#pragma once
+#ifndef SIRIDB_INITSYNC_H_
+#define SIRIDB_INITSYNC_H_
+
+typedef struct siridb_initsync_s siridb_initsync_t;
#include <stdio.h>
#include <uv.h>
#include <siri/db/series.h>
#include <siri/net/pkg.h>
-typedef struct siridb_s siridb_t;
-typedef struct sirinet_pkg_s sirinet_pkg_t;
+siridb_initsync_t * siridb_initsync_open(siridb_t * siridb, int create_new);
+void siridb_initsync_free(siridb_initsync_t ** initsync);
+void siridb_initsync_run(uv_timer_t * timer);
+void siridb_initsync_fopen(siridb_initsync_t * initsync, const char * opentype);
+const char * siridb_initsync_sync_progress(siridb_t * siridb);
-typedef struct siridb_initsync_s
+struct siridb_initsync_s
{
FILE * fp;
char * fn;
long int size;
uint32_t * next_series_id;
sirinet_pkg_t * pkg;
-} siridb_initsync_t;
+};
-siridb_initsync_t * siridb_initsync_open(siridb_t * siridb, int create_new);
-void siridb_initsync_free(siridb_initsync_t ** initsync);
-void siridb_initsync_run(uv_timer_t * timer);
-void siridb_initsync_fopen(siridb_initsync_t * initsync, const char * opentype);
-const char * siridb_initsync_sync_progress(siridb_t * siridb);
+#endif /* SIRIDB_INITSYNC_H_ */
* - initial version, 24-03-2016
*
*/
-#pragma once
-
-#include <siri/db/db.h>
-#include <qpack/qpack.h>
-#include <siri/db/forward.h>
-#include <uv.h>
-#include <siri/db/pcache.h>
+#ifndef SIRIDB_INSERT_H_
+#define SIRIDB_INSERT_H_
#define INSERT_FLAG_TEST 1
#define INSERT_FLAG_TESTED 2
INSERT_LOCAL_SUCESS,
};
-typedef struct siridb_s siridb_t;
-typedef struct qp_unpacker_s qp_unpacker_t;
-typedef struct qp_packer_s qp_packer_t;
-typedef struct qp_obj_s qp_obj_t;
-typedef struct siridb_forward_s siridb_forward_t;
+typedef struct siridb_insert_s siridb_insert_t;
+typedef struct siridb_insert_local_s siridb_insert_local_t;
+
+#include <siri/db/db.h>
+#include <qpack/qpack.h>
+#include <siri/db/forward.h>
+#include <uv.h>
+#include <siri/db/pcache.h>
-typedef struct siridb_insert_s
+ssize_t siridb_insert_assign_pools(
+ siridb_t * siridb,
+ qp_unpacker_t * unpacker,
+ qp_packer_t * packer[]);
+const char * siridb_insert_err_msg(siridb_insert_err_t err);
+siridb_insert_t * siridb_insert_new(
+ siridb_t * siridb,
+ uint16_t pid,
+ sirinet_stream_t * client);
+void siridb_insert_free(siridb_insert_t * insert);
+int siridb_insert_points_to_pools(siridb_insert_t * insert, size_t npoints);
+int insert_init_backend_local(
+ siridb_t * siridb,
+ sirinet_stream_t * client,
+ sirinet_pkg_t * pkg,
+ uint8_t flags);
+
+struct siridb_insert_s
{
uv_close_cb free_cb; /* must be on top */
uint8_t ref;
uint8_t flags;
uint16_t pid;
- uv_stream_t * client;
+ sirinet_stream_t * client;
size_t npoints; /* number of points */
uint16_t packer_size; /* number of packers (one for each pool) */
qp_packer_t * packer[];
-} siridb_insert_t;
+};
-typedef struct siridb_insert_local_s
+struct siridb_insert_local_s
{
uv_close_cb free_cb; /* must be on top */
uint8_t ref;
sirinet_promise_t * promise;
siridb_forward_t * forward;
siridb_pcache_t * pcache;
-} siridb_insert_local_t;
-
-ssize_t siridb_insert_assign_pools(
- siridb_t * siridb,
- qp_unpacker_t * unpacker,
- qp_packer_t * packer[]);
-
-const char * siridb_insert_err_msg(siridb_insert_err_t err);
+};
-siridb_insert_t * siridb_insert_new(
- siridb_t * siridb,
- uint16_t pid,
- uv_stream_t * client);
-void siridb_insert_free(siridb_insert_t * insert);
-int siridb_insert_points_to_pools(siridb_insert_t * insert, size_t npoints);
-int insert_init_backend_local(
- siridb_t * siridb,
- uv_stream_t * client,
- sirinet_pkg_t * pkg,
- uint8_t flags);
+#endif /* SIRIDB_INSERT_H_ */
--- /dev/null
+/*
+ * listener.h - contains functions for processing queries.
+ *
+ * author : Jeroen van der Heijden
+ * email : jeroen@transceptor.technology
+ * copyright : 2016, Transceptor Technology
+ *
+ * changes
+ * - initial version, 10-03-2016
+ *
+ */
+#ifndef SIRIDB_LISTENER_H_
+#define SIRIDB_LISTENER_H_
+
+#include <uv.h>
+#include <siri/grammar/grammar.h>
+
+uv_async_cb siridb_listen_enter[CLERI_END];
+uv_async_cb siridb_listen_exit[CLERI_END];
+
+void siridb_init_listener(void);
+
+#endif /* SIRIDB_LISTENER_H_ */
* - initial version, 29-07-2016
*
*/
-#pragma once
+#ifndef SIRIDB_LOOKUP_H_
+#define SIRIDB_LOOKUP_H_
#include <inttypes.h>
#include <stddef.h>
size_t len);
siridb_lookup_t * siridb_lookup_new(uint_fast16_t num_pools);
void siridb_lookup_free(siridb_lookup_t * lookup);
+
+#endif /* SIRIDB_LOOKUP_H_ */
* - initial version, 16-04-2016
*
*/
-#pragma once
+#ifndef SIRIDB_MEDIAN_H_
+#define SIRIDB_MEDIAN_H_
#include <siri/db/points.h>
#include <inttypes.h>
siridb_point_t * point,
siridb_points_t * points,
double percentage);
+
+
+#endif /* SIRIDB_MEDIAN_H_ */
* - initial version, 18-08-2016
*
*/
-#pragma once
+#ifndef SIRIDB_MISC_H_
+#define SIRIDB_MISC_H_
-#include <qpack/qpack.h>
#include <inttypes.h>
+#include <qpack/qpack.h>
+
+#define siridb_misc_get_fn(__fn, __path, __filename) \
+ char __fn[strlen(__path) + strlen(__filename) + 1]; \
+ sprintf(__fn, "%s%s", __path, __filename);
+
+/* Schema File Check
+ * Needs fn and unpacker, free unpacker in case of an error.
+ * Returns current function with -1 in case of an error and
+ * raises a SIGNAL in case of a memory error.
+ */
+#define siridb_misc_schema_check(__schema) \
+ /* read and check schema */ \
+ qp_obj_t qp_schema; \
+ if (!qp_is_array(qp_next(unpacker, NULL)) || \
+ qp_next(unpacker, &qp_schema) != QP_INT64 || \
+ qp_schema.via.int64 != __schema) \
+ { \
+ log_critical("Invalid schema detected in '%s'", fn); \
+ qp_unpacker_ff_free(unpacker); \
+ return -1; \
+ }
qp_unpacker_t * siridb_misc_open_schema_file(uint8_t schema, const char * fn);
+
+
+#endif /* SIRIDB_MISC_H_ */
* - initial version, 10-03-2016
*
*/
-#pragma once
+#ifndef SIRIDB_NODES_H_
+#define SIRIDB_NODES_H_
+
+typedef struct siridb_nodes_s siridb_nodes_t;
#include <cleri/cleri.h>
#include <siri/db/db.h>
#include <uv.h>
-typedef struct siridb_s siridb_t;
-typedef struct cleri_node_s cleri_node_t;
+void siridb_nodes_free(siridb_nodes_t * nodes);
+void siridb_nodes_next(siridb_nodes_t ** nodes);
-typedef struct siridb_nodes_s
+struct siridb_nodes_s
{
cleri_node_t * node;
uv_async_cb cb;
struct siridb_nodes_s * next;
-} siridb_nodes_t;
+};
-void siridb_nodes_free(siridb_nodes_t * nodes);
-void siridb_nodes_next(siridb_nodes_t ** nodes);
+#endif /* SIRIDB_NODES_H_ */
* - initial version, 08-10-2016
*
*/
-#pragma once
+#ifndef SIRIDB_PCACHE_H_
+#define SIRIDB_PCACHE_H_
-#include <siri/db/points.h>
+typedef struct siridb_pcache_s siridb_pcache_t;
-typedef struct siridb_pcache_s
-{
- size_t len;
- points_tp tp;
- siridb_point_t * data;
- size_t size; /* addition to normal points type */
-} siridb_pcache_t;
+#include <siri/db/points.h>
siridb_pcache_t * siridb_pcache_new(points_tp tp);
-
int siridb_pcache_add_point(
siridb_pcache_t * pcache,
uint64_t * ts,
qp_via_t * val);
-
int siridb_pcache_add_ts_obj(
siridb_pcache_t * pcache,
uint64_t * ts,
#define siridb_pcache_free(pcache) \
siridb_points_free((siridb_points_t *) pcache)
+struct siridb_pcache_s
+{
+ size_t len;
+ points_tp tp;
+ siridb_point_t * data;
+ size_t size; /* addition to normal points type */
+};
+#endif /* SIRIDB_PCACHE_H_ */
* - initial version, 04-04-2016
*
*/
-#pragma once
-#include <stdlib.h>
-#include <inttypes.h>
-#include <qpack/qpack.h>
-#include <slist/slist.h>
+#ifndef SIRIDB_POINTS_H_
+#define SIRIDB_POINTS_H_
#define POINTS_ZIP_THRESHOLD 5
TP_STRING
} points_tp;
-typedef struct siridb_point_s
-{
- uint64_t ts;
- qp_via_t val;
-} siridb_point_t;
+typedef struct siridb_point_s siridb_point_t;
+typedef struct siridb_points_s siridb_points_t;
-typedef struct siridb_points_s
-{
- size_t len;
- points_tp tp;
- siridb_point_t * data;
-} siridb_points_t;
+#include <stdlib.h>
+#include <inttypes.h>
+#include <qpack/qpack.h>
+#include <slist/slist.h>
void siridb_points_init(void);
siridb_points_t * siridb_points_new(size_t size, points_tp tp);
uint8_t * bits,
uint16_t len);
size_t siridb_points_get_size_zipped(uint16_t cinfo, uint16_t len);
-static inline size_t siridb_points_get_size_log(size_t cinfo)
-{
- return cinfo & 0x8000 ? (cinfo ^ 0x8000) << 10 : cinfo;
-}
#define siridb_points_zip(p__, s__, e__, c__, z__) \
((p__)->tp == TP_INT) ? \
((p__)->tp == TP_DOUBLE) ? \
siridb_points_zip_double(p__, s__, e__, c__, z__) : \
siridb_points_zip_string(p__, s__, e__, c__, z__)
+
+struct siridb_point_s
+{
+ uint64_t ts;
+ qp_via_t val;
+};
+
+struct siridb_points_s
+{
+ size_t len;
+ points_tp tp;
+ siridb_point_t * data;
+};
+
+static inline size_t siridb_points_get_size_log(size_t cinfo)
+{
+ return cinfo & 0x8000 ? (cinfo ^ 0x8000) << 10 : cinfo;
+}
+
+
+#endif /* SIRIDB_POINTS_H_ */
* - initial version, 25-03-2016
*
*/
-#pragma once
+#ifndef SIRIDB_POOL_H_
+#define SIRIDB_POOL_H_
+
+typedef struct siridb_pool_s siridb_pool_t;
+typedef struct siridb_pool_walker_s siridb_pool_walker_t;
#include <cexpr/cexpr.h>
#include <inttypes.h>
#include <siri/net/pkg.h>
#include <siri/net/promise.h>
-typedef struct siridb_s siridb_t;
-typedef struct siridb_server_s siridb_server_t;
-typedef struct cexpr_condition_s cexpr_condition_t;
-typedef struct sirinet_promise_s sirinet_promise_t;
-
-typedef void (* sirinet_promise_cb)(
- sirinet_promise_t * promise,
- sirinet_pkg_t * pkg,
- int status);
-
-typedef struct siridb_pool_s
-{
- uint16_t len;
- siridb_server_t * server[2];
-} siridb_pool_t;
-
-typedef struct siridb_pool_walker_s
-{
- uint_fast16_t pool;
- uint_fast8_t servers;
- size_t series;
-} siridb_pool_walker_t;
-
-
int siridb_pool_cexpr_cb(siridb_pool_walker_t * wpool, cexpr_condition_t * cond);
int siridb_pool_online(siridb_pool_t * pool);
int siridb_pool_available(siridb_pool_t * pool);
void * data,
int flags);
void siridb_pool_add_server(siridb_pool_t * pool, siridb_server_t * server);
+
+
+struct siridb_pool_s
+{
+ uint16_t len;
+ siridb_server_t * server[2];
+};
+
+struct siridb_pool_walker_s
+{
+ uint_fast16_t pool;
+ uint_fast8_t servers;
+ size_t series;
+};
+
+#endif /* SIRIDB_POOL_H_ */
* - initial version, 25-03-2016
*
*/
-#pragma once
+#ifndef SIRIDB_POOLS_H_
+#define SIRIDB_POOLS_H_
+
+typedef struct siridb_pools_s siridb_pools_t;
#include <inttypes.h>
#include <siri/db/db.h>
#include <siri/db/server.h>
#include <siri/net/pkg.h>
#include <siri/net/promise.h>
+#include <siri/net/promises.h>
#include <slist/slist.h>
#include <siri/db/lookup.h>
-typedef struct siridb_pool_s siridb_pool_t;
-typedef struct siridb_s siridb_t;
-typedef struct siridb_server_s siridb_server_t;
-
-typedef void (* sirinet_promises_cb)(
- slist_t * promises,
- void * data);
-
-typedef struct siridb_pools_s
-{
- uint16_t len;
- siridb_pool_t * pool;
- siridb_lookup_t * lookup;
- siridb_lookup_t * prev_lookup;
-} siridb_pools_t;
-
void siridb_pools_init(siridb_t * siridb);
void siridb_pools_free(siridb_pools_t * pools);
siridb_pool_t * siridb_pools_append(
sirinet_promises_cb cb,
void * data,
int flags);
+
+struct siridb_pools_s
+{
+ uint16_t len;
+ siridb_pool_t * pool;
+ siridb_lookup_t * lookup;
+ siridb_lookup_t * prev_lookup;
+};
+
+#endif /* SIRIDB_POOLS_H_ */
* - initial version, 08-08-2016
*
*/
-#pragma once
-
-#include <cleri/cleri.h>
+#ifndef SIRIDB_PRESUF_H_
+#define SIRIDB_PRESUF_H_
typedef struct siridb_presuf_s siridb_presuf_t;
-typedef struct siridb_presuf_s
-{
- char * prefix;
- char * suffix;
- size_t len; /* prefix len + suffix len + terminator char */
- siridb_presuf_t * prev;
-} siridb_presuf_t;
-
+#include <cleri/cleri.h>
void siridb_presuf_free(siridb_presuf_t * presuf);
siridb_presuf_t * siridb_presuf_add(
siridb_presuf_t * presuf,
const char * name,
size_t len);
+
+struct siridb_presuf_s
+{
+ char * prefix;
+ char * suffix;
+ size_t len; /* prefix len + suffix len + terminator char */
+ siridb_presuf_t * prev;
+};
+
+#endif /* SIRIDB_PRESUF_H_ */
* - initial version, 17-03-2016
*
*/
-#pragma once
+#ifndef SIRIDB_PROPS_H_
+#define SIRIDB_PROPS_H_
#include <siri/grammar/gramp.h>
#include <siri/db/db.h>
#include <qpack/qpack.h>
-struct siridb_s;
-struct qp_packer_s;
-
-
void siridb_init_props(void);
typedef void (* siridb_props_cb)(
- struct siridb_s * siridb,
- struct qp_packer_s * packer,
+ siridb_t * siridb,
+ qp_packer_t * packer,
int flags);
siridb_props_cb siridb_props[KW_COUNT];
char * who_am_i;
+
+#endif /* SIRIDB_PROPS_H_ */
--- /dev/null
+/*
+ * queries.h - Querie helpers for listener
+ *
+ * author : Jeroen van der Heijden
+ * email : jeroen@transceptor.technology
+ * copyright : 2016, Transceptor Technology
+ *
+ * changes
+ * - initial version, 03-05-2016
+ *
+ */
+#ifndef SIRIDB_QUERIES_H_
+#define SIRIDB_QUERIES_H_
+
+#include <uv.h>
+#include <inttypes.h>
+#include <imap/imap.h>
+#include <slist/slist.h>
+#include <cexpr/cexpr.h>
+#include <cleri/cleri.h>
+#include <ctree/ctree.h>
+#include <siri/db/presuf.h>
+#include <siri/db/group.h>
+#include <siri/db/series.h>
+#include <siri/db/user.h>
+#include <pcre2.h>
+
+#define QUERIES_IGNORE_DROP_THRESHOLD 1
+#define QUERIES_SKIP_GET_POINTS 2
+
+enum
+{
+ QUERIES_ALTER,
+ QUERIES_COUNT,
+ QUERIES_DROP,
+ QUERIES_LIST,
+ QUERIES_SELECT
+};
+
+typedef enum
+{
+ QUERY_ALTER_NONE,
+ QUERY_ALTER_DATABASE,
+ QUERY_ALTER_GROUP,
+ QUERY_ALTER_SERVER,
+ QUERY_ALTER_SERVERS,
+ QUERY_ALTER_USER
+} query_alter_tp;
+
+#define QUERY_DEF \
+uint8_t tp; \
+uint8_t flags; \
+imap_t * series_map; \
+imap_t * series_tmp; \
+imap_t * pmap; \
+slist_t * slist; \
+size_t slist_index; \
+imap_update_cb update_cb; \
+cexpr_t * where_expr; \
+pcre2_code * regex; \
+pcre2_match_data * match_data;
+
+typedef struct query_wrapper_s query_wrapper_t;
+typedef union query_alter_u query_alter_via_t;
+typedef struct query_alter_s query_alter_t;
+typedef struct query_count_s query_count_t;
+typedef struct query_drop_s query_drop_t;
+typedef struct query_list_s query_list_t;
+typedef struct query_select_s query_select_t;
+
+query_alter_t * query_alter_new(void);
+void query_alter_free(uv_handle_t * handle);
+
+query_count_t * query_count_new(void);
+void query_count_free(uv_handle_t * handle);
+
+query_drop_t * query_drop_new(void);
+void query_drop_free(uv_handle_t * handle);
+
+query_list_t * query_list_new(void);
+void query_list_free(uv_handle_t * handle);
+
+query_select_t * query_select_new(void);
+void query_select_free(uv_handle_t * handle);
+
+void query_help_free(uv_handle_t * handle);
+
+/* wrappers */
+struct query_wrapper_s
+{
+ QUERY_DEF
+};
+
+union query_alter_u
+{
+ siridb_group_t * group;
+ siridb_server_t * server;
+ siridb_user_t * user;
+ void * dummy;
+};
+
+struct query_alter_s
+{
+ QUERY_DEF
+ query_alter_tp alter_tp;
+ query_alter_via_t via;
+ size_t n; /* can be used as counter */
+};
+
+struct query_count_s
+{
+ QUERY_DEF
+ size_t n; /* can be used as counter */
+};
+
+struct query_drop_s
+{
+ QUERY_DEF
+ size_t n; /* keep a counter for number of drops. */
+ slist_t * shards_list;
+};
+
+struct query_list_s
+{
+ QUERY_DEF
+ slist_t * props; /* will be freed */
+ size_t limit;
+};
+
+struct query_select_s
+{
+ QUERY_DEF
+ size_t n;
+ size_t nselects;
+ uint64_t * start_ts; /* will NOT be freed */
+ uint64_t * end_ts; /* will NOT be freed */
+ siridb_presuf_t * presuf;
+ char * merge_as;
+ ct_t * result;
+ imap_t * points_map; /* points_map for caching */
+ slist_t * alist; /* aggregation list (can be used multiple times)*/
+ slist_t * mlist; /* merge aggregation list */
+};
+
+#endif /* SIRIDB_QUERIES_H_ */
* - initial version, 10-03-2016
*
*/
-#pragma once
+#ifndef SIRIDB_QUERY_H_
+#define SIRIDB_QUERY_H_
#define SIRIDB_QUERY_FLAG_MASTER 1
#define SIRIDB_QUERY_FLAG_REBUILD 2
SIRIDB_QUERY_FWD_UPDATE /* Forward to all pools, upd repl(*) */
} siridb_query_fwd_t;
-
-#include <uv.h>
-#include <inttypes.h>
-#include <sys/time.h>
-#include <cleri/cleri.h>
-#include <qpack/qpack.h>
-#include <siri/db/time.h>
-#include <siri/db/nodes.h>
-#include <siri/db/series.h>
-#include <siri/db/db.h>
-#include <siri/net/protocol.h>
-
-typedef struct cleri_parse_s cleri_parse_t;
-typedef struct siridb_node_list_s siridb_node_list_t;
-
typedef enum siridb_err_tp
{
SIRIDB_SUCCESS,
} siridb_err_t;
-typedef struct siridb_query_s
-{
- uv_close_cb free_cb; /* must be on top */
- uint8_t ref;
- uint8_t flags;
- uint16_t pid;
- float factor;
- void * data;
- uv_stream_t * client;
- char * q;
- char err_msg[SIRIDB_MAX_SIZE_ERR_MSG];
- qp_packer_t * packer;
- qp_packer_t * timeit;
- cleri_parse_t * pr;
- siridb_nodes_t * nodes;
- struct timespec start;
-} siridb_query_t;
+typedef struct siridb_query_s siridb_query_t;
+
+#include <uv.h>
+#include <inttypes.h>
+#include <sys/time.h>
+#include <cleri/cleri.h>
+#include <qpack/qpack.h>
+#include <siri/db/time.h>
+#include <siri/db/nodes.h>
+#include <siri/db/series.h>
+#include <siri/db/db.h>
+#include <siri/net/protocol.h>
void siridb_query_run(
uint16_t pid,
- uv_stream_t * client,
+ sirinet_stream_t * client,
const char * q,
size_t q_len,
float factor,
siridb_query_t * query,
qp_unpacker_t * unpacker);
int siridb_query_err_from_pkg(siridb_query_t * query, sirinet_pkg_t * pkg);
+
+struct siridb_query_s
+{
+ uv_close_cb free_cb; /* must be on top */
+ uint8_t ref;
+ uint8_t flags;
+ uint16_t pid;
+ float factor;
+ void * data;
+ sirinet_stream_t * client;
+ char * q;
+ char err_msg[SIRIDB_MAX_SIZE_ERR_MSG];
+ qp_packer_t * packer;
+ qp_packer_t * timeit;
+ cleri_parse_t * pr;
+ siridb_nodes_t * nodes;
+ struct timespec start;
+};
+
+#endif /* SIRIDB_QUERY_H_ */
* - initial version, 04-08-2016
*
*/
-#pragma once
+#ifndef SIRIDB_RE_H_
+#define SIRIDB_RE_H_
#define PCRE2_CODE_UNIT_WIDTH 8
const char * source,
size_t len,
char * err_msg);
+
+
+#endif /* SIRIDB_RE_H_ */
* - initial version, 27-07-2016
*
*/
-#pragma once
+#ifndef SIRIDB_REINDEX_H_
+#define SIRIDB_REINDEX_H_
+
+#define REINDEX_FN ".reindex"
+
+typedef struct siridb_reindex_s siridb_reindex_t;
#include <inttypes.h>
#include <uv.h>
#include <siri/db/db.h>
#include <siri/db/series.h>
-#define REINDEX_FN ".reindex"
-
-typedef struct siridb_s siridb_t;
-typedef struct siridb_series_s siridb_series_t;
+siridb_reindex_t * siridb_reindex_open(siridb_t * siridb, int create_new);
+void siridb_reindex_fopen(siridb_reindex_t * reindex, const char * opentype);
+void siridb_reindex_free(siridb_reindex_t ** reindex);
+void siridb_reindex_status_update(siridb_t * siridb);
+void siridb_reindex_close(siridb_reindex_t * reindex);
+void siridb_reindex_start(uv_timer_t * timer);
+const char * siridb_reindex_progress(siridb_t * siridb);
-typedef struct siridb_reindex_s
+struct siridb_reindex_s
{
FILE * fp;
char * fn;
siridb_series_t * series;
siridb_server_t * server;
uv_timer_t * timer;
-} siridb_reindex_t;
+};
-siridb_reindex_t * siridb_reindex_open(siridb_t * siridb, int create_new);
-void siridb_reindex_fopen(siridb_reindex_t * reindex, const char * opentype);
-void siridb_reindex_free(siridb_reindex_t ** reindex);
-void siridb_reindex_status_update(siridb_t * siridb);
-void siridb_reindex_close(siridb_reindex_t * reindex);
-void siridb_reindex_start(uv_timer_t * timer);
-const char * siridb_reindex_progress(siridb_t * siridb);
+#endif /* SIRIDB_REINDEX_H_ */
* - initial version, 11-07-2016
*
*/
-#pragma once
-
-#include <uv.h>
-#include <siri/db/db.h>
-#include <siri/db/initsync.h>
-#include <siri/net/pkg.h>
-
-typedef struct siridb_initsync_s siridb_initsync_t;
-typedef struct siridb_s siridb_t;
-typedef struct sirinet_pkg_s sirinet_pkg_t;
+#ifndef SIRIDB_REPLICATE_H_
+#define SIRIDB_REPLICATE_H_
typedef enum
{
REPLICATE_CLOSED
} siridb_replicate_status_t;
-typedef struct siridb_replicate_s
-{
- siridb_replicate_status_t status;
- uv_timer_t * timer;
- siridb_initsync_t * initsync;
-} siridb_replicate_t;
+typedef struct siridb_replicate_s siridb_replicate_t;
+
+#include <uv.h>
+#include <siri/db/db.h>
+#include <siri/db/initsync.h>
+#include <siri/net/pkg.h>
int siridb_replicate_init(siridb_t * siridb, siridb_initsync_t * initsync);
void siridb_replicate_free(siridb_replicate_t ** replicate);
int flags);
#define siridb_replicate_is_idle(replicate) (replicate->status == REPLICATE_IDLE)
+
+struct siridb_replicate_s
+{
+ siridb_replicate_status_t status;
+ uv_timer_t * timer;
+ siridb_initsync_t * initsync;
+};
+
+#endif /* SIRIDB_REPLICATE_H_ */
* - initial version, 29-03-2016
*
*/
-#pragma once
-
-#include <inttypes.h>
-#include <siri/db/db.h>
-#include <siri/db/points.h>
-#include <siri/db/pcache.h>
-#include <siri/db/buffer.h>
-#include <qpack/qpack.h>
-#include <cexpr/cexpr.h>
-
-typedef struct siridb_s siridb_t;
-typedef struct siridb_buffer_s siridb_buffer_t;
-typedef struct siridb_points_s siridb_points_t;
-typedef struct siridb_shard_s siridb_shard_t;
-
-typedef points_tp series_tp;
+#ifndef SIRIDB_SERIES_H_
+#define SIRIDB_SERIES_H_
/* Series Flags */
#define SIRIDB_SERIES_HAS_OVERLAP 1
extern const char series_type_map[3][8];
-typedef struct idx_s
-{
- siridb_shard_t * shard;
- uint32_t pos;
- uint16_t len;
- uint16_t cinfo; /* reserved for log values or used for compression */
- uint64_t start_ts;
- uint64_t end_ts;
-} idx_t;
+typedef struct idx_s idx_t;
+typedef struct siridb_series_s siridb_series_t;
+
+#include <inttypes.h>
+
+#include <siri/db/points.h>
+typedef points_tp series_tp;
-typedef struct siridb_series_s
+#include <siri/db/db.h>
+#include <siri/db/pcache.h>
+#include <siri/db/buffer.h>
+#include <qpack/qpack.h>
+#include <cexpr/cexpr.h>
+
+/* order here matters since shard.h is using a full series definition */
+struct siridb_series_s
{
uint32_t ref; /* keep ref on top */
uint32_t id;
char * name;
idx_t * idx;
siridb_t * siridb;
-} siridb_series_t;
+};
+#include <siri/db/shard.h>
int siridb_series_load(siridb_t * siridb);
-
siridb_series_t * siridb_series_new(
siridb_t * siridb,
const char * series_name,
uint8_t tp);
-
int siridb_series_add_idx(
siridb_series_t *__restrict series,
siridb_shard_t *__restrict shard,
uint32_t pos,
uint16_t len,
uint16_t cinfo);
-
int siridb_series_add_point(
siridb_t *__restrict siridb,
siridb_series_t *__restrict series,
uint64_t * ts,
qp_via_t * val);
-
int siridb_series_add_pcache(
siridb_t *__restrict siridb,
siridb_series_t *__restrict series,
siridb_pcache_t *__restrict pcache);
-
siridb_points_t * siridb_series_get_points(
siridb_series_t *__restrict series,
uint64_t *__restrict start_ts,
uint64_t *__restrict end_ts);
-
void siridb_series_remove_shard(
siridb_t *__restrict siridb,
siridb_series_t *__restrict series,
siridb_shard_t *__restrict shard);
-
int siridb_series_optimize_shard(
siridb_t *__restrict siridb,
siridb_series_t *__restrict series,
siridb_shard_t *__restrict shard);
-
-
void siridb_series_update_props(siridb_t * siridb, siridb_series_t * series);
int siridb_series_cexpr_cb(siridb_series_t * series, cexpr_condition_t * cond);
int siridb_series_replicate_file(siridb_t * siridb);
#define siridb_series_server_id(series) \
((series->flags & SIRIDB_SERIES_IS_SERVER_ONE) == SIRIDB_SERIES_IS_SERVER_ONE)
+
+struct idx_s
+{
+ siridb_shard_t * shard;
+ uint32_t pos;
+ uint16_t len;
+ uint16_t cinfo; /* reserved for log values or used for compression */
+ uint64_t start_ts;
+ uint64_t end_ts;
+};
+
+
+
+#endif /* SIRIDB_SERIES_H_ */
* - initial version, 17-03-2016
*
*/
-#pragma once
-
-#include <uuid/uuid.h>
-#include <stdint.h>
-#include <siri/db/db.h>
-#include <imap/imap.h>
-#include <cexpr/cexpr.h>
-#include <uv.h>
-#include <siri/net/promise.h>
-#include <siri/net/pkg.h>
+#ifndef SIRIDB_SERVER_H_
+#define SIRIDB_SERVER_H_
#define FLAG_KEEP_PKG 1
#define FLAG_ONLY_CHECK_ONLINE 2
#define siridb_server_self_accessible(server) \
(server->flags == SERVER__SELF_ONLINE || server->flags == SERVER__SELF_REINDEXING)
+typedef struct siridb_server_s siridb_server_t;
+typedef struct siridb_server_walker_s siridb_server_walker_t;
+typedef struct siridb_server_async_s siridb_server_async_t;
-
-typedef struct siridb_s siridb_t;
-typedef struct sirinet_promise_s sirinet_promise_t;
-typedef void (* sirinet_promise_cb)(
- sirinet_promise_t * promise,
- sirinet_pkg_t * pkg,
- int status);
-
-typedef struct siridb_server_s
-{
- uint16_t ref; /* keep ref on top */
- uint16_t port;
- uint16_t pool;
- uint8_t flags; /* do not use flags above 16384 */
- uint8_t id; /* set when added to a pool to either 0 or 1 */
- char * name; /* this is a format for address:port but we use it a lot */
- char * address;
- imap_t * promises;
- uv_tcp_t * socket;
- uint16_t pid;
- /* fixed server properties */
- uint8_t ip_support;
- uint8_t pad0;
- uint32_t startup_time;
- char * libuv;
- char * version;
- char * dbpath;
- char * buffer_path;
- size_t buffer_size;
- uuid_t uuid;
-} siridb_server_t;
-
-typedef struct siridb_server_walker_s
-{
- siridb_server_t * server;
- siridb_t * siridb;
-} siridb_server_walker_t;
-
-typedef struct siridb_server_async_s
-{
- uint16_t pid;
- uv_stream_t * client;
-} siridb_server_async_t;
-
+#include <uuid/uuid.h>
+#include <stdint.h>
+#include <siri/db/db.h>
+#include <imap/imap.h>
+#include <cexpr/cexpr.h>
+#include <uv.h>
+#include <siri/net/promise.h>
+#include <siri/net/pkg.h>
+#include <siri/net/stream.h>
siridb_server_t * siridb_server_new(
const char * uuid,
uint16_t port,
uint16_t pool);
-/*
- * Returns < 0 if the uuid from server A is less than uuid from server B.
- * Returns > 0 if the uuid from server A is greater than uuid from server B.
- * Returns 0 when uuid server A and B are equal.
- */
-static inline int siridb_server_cmp(siridb_server_t * sa, siridb_server_t * sb)
-{
- return uuid_compare(sa->uuid, sb->uuid);
-}
+
void siridb_server_connect(siridb_t * siridb, siridb_server_t * server);
int siridb_server_send_pkg(
*/
#define siridb_server_decref(server__) \
if (!--server__->ref) siridb__server_free(server__)
+
+struct siridb_server_s
+{
+ uint16_t ref; /* keep ref on top */
+ uint16_t port;
+ uint16_t pool;
+ uint8_t flags; /* do not use flags above 16384 */
+ uint8_t id; /* set when added to a pool to either 0 or 1 */
+ char * name; /* this is a format for address:port but we use it a lot */
+ char * address;
+ imap_t * promises;
+ sirinet_stream_t * client;
+ uint16_t pid;
+ /* fixed server properties */
+ uint8_t ip_support;
+ uint8_t pad0;
+ uint32_t startup_time;
+ char * libuv;
+ char * version;
+ char * dbpath;
+ char * buffer_path;
+ size_t buffer_size;
+ uuid_t uuid;
+};
+
+struct siridb_server_walker_s
+{
+ siridb_server_t * server;
+ siridb_t * siridb;
+};
+
+struct siridb_server_async_s
+{
+ uint16_t pid;
+ sirinet_stream_t * client;
+};
+
+/*
+ * Returns < 0 if the uuid from server A is less than uuid from server B.
+ * Returns > 0 if the uuid from server A is greater than uuid from server B.
+ * Returns 0 when uuid server A and B are equal.
+ */
+static inline int siridb_server_cmp(siridb_server_t * sa, siridb_server_t * sb)
+{
+ return uuid_compare(sa->uuid, sb->uuid);
+}
+
+#endif /* SIRIDB_SERVER_H_ */
* - initial version, 10-06-2016
*
*/
-#pragma once
+#ifndef SIRIDB_SERVERS_H_
+#define SIRIDB_SERVERS_H_
#include <siri/db/db.h>
#include <uuid/uuid.h> /* install: apt-get install uuid-dev */
#include <siri/net/promise.h>
-typedef struct siridb_s siridb_t;
-
int siridb_servers_load(siridb_t * siridb);
void siridb_servers_free(llist_t * servers);
siridb_server_t * siridb_servers_by_uuid(llist_t * servers, uuid_t uuid);
int siridb_servers_save(siridb_t * siridb);
int siridb_servers_register(siridb_t * siridb, siridb_server_t * server);
slist_t * siridb_servers_other2slist(siridb_t * siridb);
+
+#endif /* SIRIDB_SERVERS_H_ */
* - initial version, 04-04-2016
*
*/
-#pragma once
+#ifndef SIRIDB_SHARD_H_
+#define SIRIDB_SHARD_H_
+
-#include <siri/db/db.h>
-#include <siri/db/points.h>
-#include <siri/db/series.h>
-#include <siri/file/handler.h>
-#include <stdio.h>
/* flags */
#define SIRIDB_SHARD_OK 0
#define SIRIDB_SHARD_TP_NUMBER 0
#define SIRIDB_SHARD_TP_LOG 1
-extern const char shard_type_map[2][7];
-
#define SIRIDB_SHARD_STATUS_STR_MAX 128
-typedef struct siridb_shard_flags_repr_s
-{
- const char * repr;
- uint8_t flag;
-} siridb_shard_flags_repr_t;
-
-typedef struct siridb_s siridb_t;
-typedef struct siridb_points_s siridb_points_t;
-typedef struct siridb_series_s siridb_series_t;
-typedef struct idx_s idx_t;
+extern const char shard_type_map[2][7];
+typedef struct siridb_shard_flags_repr_s siridb_shard_flags_repr_t;
typedef struct siridb_shard_s siridb_shard_t;
+typedef struct siridb_shard_view_s siridb_shard_view_t;
-
-typedef struct siridb_shard_s
-{
- uint32_t ref; /* keep ref on top */
- uint8_t tp; /* TP_NUMBER, TP_LOG */
- uint8_t flags;
- uint16_t max_chunk_sz;
- uint64_t id;
- size_t len;
- size_t size;
- siri_fp_t * fp;
- char * fn;
- siridb_shard_t * replacing;
-} siridb_shard_t;
-
-typedef struct siridb_shard_view_s
-{
- siridb_shard_t * shard;
- siridb_server_t * server;
- uint64_t start;
- uint64_t end;
-} siridb_shard_view_t;
+#include <stdio.h>
+#include <siri/db/db.h>
+#include <siri/db/points.h>
+#include <siri/db/series.h>
+#include <siri/file/handler.h>
siridb_shard_t * siridb_shard_create(
siridb_t * siridb,
int siridb_shard_status(char * str, siridb_shard_t * shard);
int siridb_shard_load(siridb_t * siridb, uint64_t id);
void siridb_shard_drop(siridb_shard_t * shard, siridb_t * siridb);
-
size_t siridb_shard_write_points(
siridb_t * siridb,
siridb_series_t * series,
uint_fast32_t end,
FILE * idx_fp,
uint16_t * cinfo);
-
typedef int (*siridb_shard_get_points_cb)(
siridb_points_t * points,
idx_t * idx,
uint64_t * start_ts,
uint64_t * end_ts,
uint8_t has_overlap);
-
int siridb_shard_get_points_num32(
siridb_points_t * points,
idx_t * idx,
uint64_t * start_ts,
uint64_t * end_ts,
uint8_t has_overlap);
-
int siridb_shard_get_points_num64(
siridb_points_t * points,
idx_t * idx,
uint64_t * start_ts,
uint64_t * end_ts,
uint8_t has_overlap);
-
int siridb_shard_get_points_log32(
siridb_points_t * points,
idx_t * idx,
uint64_t * start_ts,
uint64_t * end_ts,
uint8_t has_overlap);
-
int siridb_shard_get_points_log64(
siridb_points_t * points,
idx_t * idx,
uint64_t * start_ts,
uint64_t * end_ts,
uint8_t has_overlap);
-
int siridb_shard_get_points_num_compressed(
siridb_points_t * points,
idx_t * idx,
uint64_t * start_ts,
uint64_t * end_ts,
uint8_t has_overlap);
-
int siridb_shard_get_points_log_compressed(
siridb_points_t * points,
idx_t * idx,
uint64_t * start_ts,
uint64_t * end_ts,
uint8_t has_overlap);
-
int siridb_shard_optimize(siridb_shard_t * shard, siridb_t * siridb);
void siridb__shard_free(siridb_shard_t * shard);
void siridb__shard_decref(siridb_shard_t * shard);
+struct siridb_shard_flags_repr_s
+{
+ const char * repr;
+ uint8_t flag;
+};
+
+struct siridb_shard_s
+{
+ uint32_t ref; /* keep ref on top */
+ uint8_t tp; /* TP_NUMBER, TP_LOG */
+ uint8_t flags;
+ uint16_t max_chunk_sz;
+ uint64_t id;
+ size_t len;
+ size_t size;
+ siri_fp_t * fp;
+ char * fn;
+ siridb_shard_t * replacing;
+};
+
+struct siridb_shard_view_s
+{
+ siridb_shard_t * shard;
+ siridb_server_t * server;
+ uint64_t start;
+ uint64_t end;
+};
+
static inline siridb_shard_get_points_cb siridb_shard_get_points_callback(
uint8_t shard_flags,
siridb_series_t * series)
char Name__[Len__ + 1]; \
memcpy(Name__, Fn__, Len__ - 3); \
memcpy(Name__ + Len__ - 3, "idx", 4)
+
+#endif /* SIRIDB_SHARD_H_ */
* - initial version, 04-04-2016
*
*/
-#pragma once
-
-#include <siri/db/db.h>
+#ifndef SIRIDB_SHARDS_H_
+#define SIRIDB_SHARDS_H_
#define SIRIDB_SHARDS_PATH "shards/"
-typedef struct siridb_s siridb_t;
+#include <siri/db/db.h>
int siridb_shards_load(siridb_t * siridb);
int siridb_shards_add_points(
siridb_t * siridb,
siridb_series_t * series,
siridb_points_t * points);
+
+#endif /* SIRIDB_SHARDS_H_ */
* - initial version, 31-10-2016
*
*/
-#pragma once
+#ifndef SIRIDB_TASKS_H_
+#define SIRIDB_TASKS_H_
+
+typedef struct siridb_tasks_s siridb_tasks_t;
#include <time.h>
#include <inttypes.h>
#include <timeit/timeit.h>
-typedef struct siridb_tasks_s
-{
- struct timespec _timeit;
- uint64_t active;
- double idle_time;
-} siridb_tasks_t;
-
void siridb_tasks_init(siridb_tasks_t * tasks);
#define siridb_tasks_inc(tasks) \
#define siridb_tasks_dec(tasks) \
if (!--tasks.active) timeit_start(&tasks._timeit)
+
+struct siridb_tasks_s
+{
+ struct timespec _timeit;
+ uint64_t active;
+ double idle_time;
+};
+
+#endif /* SIRIDB_TASKS_H_ */
* - initial version, 09-03-2016
*
*/
-#pragma once
+#ifndef SIRIDB_TIME_H_
+#define SIRIDB_TIME_H_
-#include <inttypes.h>
-#include <siri/db/db.h>
-#include <stddef.h>
-#include <time.h>
-
-typedef struct siridb_s siridb_t;
-struct timespec;
-
-typedef enum siridb_time_tp
+typedef enum
{
SIRIDB_TIME_DEFAULT=-1, /* use this when asking for the db default */
SIRIDB_TIME_SECONDS,
SIRIDB_TIME_END
} siridb_timep_t;
-typedef struct siridb_time_s
+typedef struct siridb_time_s siridb_time_t;
+
+#include <inttypes.h>
+#include <siri/db/db.h>
+#include <stddef.h>
+#include <time.h>
+
+const char * siridb_time_short_map[SIRIDB_TIME_END];
+siridb_time_t * siridb_time_new(siridb_timep_t precision);
+uint32_t siridb_time_in_seconds(siridb_t * siridb, int64_t ts);
+uint64_t siridb_time_now(siridb_t * siridb, struct timespec now);
+uint64_t siridb_time_parse(const char * str, size_t len);
+
+struct siridb_time_s
{
siridb_timep_t precision;
uint32_t factor;
size_t ts_sz;
-} siridb_time_t;
-
-siridb_time_t * siridb_time_new(siridb_timep_t precision);
-
-const char * siridb_time_short_map[SIRIDB_TIME_END];
+};
static inline int siridb_int64_valid_ts(siridb_time_t * time, int64_t ts)
{
ts >= 0 && ts < 4294967296 : ts >= 0;
}
-uint32_t siridb_time_in_seconds(siridb_t * siridb, int64_t ts);
-
-uint64_t siridb_time_now(siridb_t * siridb, struct timespec now);
-
-uint64_t siridb_time_parse(const char * str, size_t len);
+#endif /* SIRIDB_TIME_H_ */
* - initial version, 10-03-2016
*
*/
-#pragma once
+#ifndef SIRIDB_USER_H_
+#define SIRIDB_USER_H_
+
+typedef struct siridb_user_s siridb_user_t;
#include <qpack/qpack.h>
#include <inttypes.h>
#include <siri/db/access.h>
#include <cexpr/cexpr.h>
-typedef struct siridb_s siridb_t;
-
-typedef struct siridb_user_s
-{
- uint16_t ref;
- uint16_t pad0;
- uint32_t access_bit;
- char * name;
- char * password; /* keeps an encrypted password */
-} siridb_user_t;
-
siridb_user_t * siridb_user_new(void);
void siridb_user_prop(siridb_user_t * user, qp_packer_t * packer, int prop);
int siridb_user_set_name(
*/
#define siridb_user_decref(user__) \
if (!--user__->ref) siridb__user_free(user__)
+
+struct siridb_user_s
+{
+ uint16_t ref;
+ uint16_t pad0;
+ uint32_t access_bit;
+ char * name;
+ char * password; /* keeps an encrypted password */
+};
+#endif /* SIRIDB_USER_H_ */
* - initial version, 04-05-2016
*
*/
-#pragma once
+#ifndef SIRIDB_USERS_H_
+#define SIRIDB_USERS_H_
#include <inttypes.h>
#include <siri/db/db.h>
#include <siri/db/user.h>
#include <llist/llist.h>
-typedef struct siridb_s siridb_t;
-typedef struct siridb_user_s siridb_user_t;
-
int siridb_users_load(siridb_t * siridb);
void siridb_users_free(llist_t * users);
int siridb_users_add_user(
const char * password);
int siridb_users_save(siridb_t * siridb);
ssize_t siridb_users_get_file(char ** buffer, siridb_t * siridb);
+
+#endif /* SIRIDB_USERS_H_ */
* - initial version, 10-08-2016
*
*/
-#pragma once
+#ifndef SIRIDB_VARIANCE_H_
+#define SIRIDB_VARIANCE_H_
#include <siri/db/points.h>
double siridb_variance(siridb_points_t * points);
+
+#endif /* SIRIDB_VARIANCE_H_ */
* - initial version, 13-06-2016
*
*/
-#pragma once
+#ifndef SIRIDB_WALKER_H_
+#define SIRIDB_WALKER_H_
+
+typedef struct siridb_walker_s siridb_walker_t;
#include <cleri/cleri.h>
#include <siri/db/nodes.h>
#include <uv.h>
-typedef struct siridb_s siridb_t;
-typedef struct siridb_nodes_s siridb_nodes_t;
-typedef struct cleri_node_s cleri_node_t;
-
-typedef struct siridb_walker_s
-{
- siridb_t * siridb;
- uint64_t now;
- uint8_t * flags;
- siridb_nodes_t * start;
- siridb_nodes_t * enter_nodes;
- siridb_nodes_t * exit_nodes;
-} siridb_walker_t;
-
siridb_walker_t * siridb_walker_new(
siridb_t * siridb,
const uint64_t now,
siridb_walker_t * walker,
cleri_node_t * node,
uv_async_cb cb);
-
int siridb_walker_insert(
siridb_walker_t * walker,
cleri_node_t * node,
uv_async_cb cb);
+
+struct siridb_walker_s
+{
+ siridb_t * siridb;
+ uint64_t now;
+ uint8_t * flags;
+ siridb_nodes_t * start;
+ siridb_nodes_t * enter_nodes;
+ siridb_nodes_t * exit_nodes;
+};
+
+#endif /* SIRIDB_WALKER_H_ */
* - initial version, 30-06-2016
*
*/
-#pragma once
+#ifndef SIRI_ERR_H_
+#define SIRI_ERR_H_
#include <logger/logger.h>
#include <signal.h>
+
/* value should be 0,
* any other value indicates a critical error has occurred */
extern int siri_err;
raise(SIGABRT); \
if (!siri_err) siri_err = SIGABRT;
-
+#endif /* SIRI_ERR_H_ */
* - initial version, 08-04-2016
*
*/
-#pragma once
+#ifndef SIRI_FH_H_
+#define SIRI_FH_H_
+
+typedef struct siri_fh_s siri_fh_t;
#include <inttypes.h>
#include <siri/file/pointer.h>
-typedef struct siri_fh_s
-{
- uint16_t size;
- uint16_t idx;
- siri_fp_t ** fpointers;
-} siri_fh_t;
-
siri_fh_t * siri_fh_new(uint16_t size);
-
void siri_fh_free(siri_fh_t * fh);
-
int siri_fopen(
siri_fh_t * fh,
siri_fp_t * fp,
const char * fn,
const char * modes);
+struct siri_fh_s
+{
+ uint16_t size;
+ uint16_t idx;
+ siri_fp_t ** fpointers;
+};
+
+#endif /* SIRI_FH_H_ */
* - initial version, 08-04-2016
*
*/
-#pragma once
+#ifndef SIRI_FP_H_
+#define SIRI_FP_H_
+
+typedef struct siri_fp_s siri_fp_t;
#include <stdio.h>
#include <inttypes.h>
+siri_fp_t * siri_fp_new(void);
+/* closes the file pointer, decrement reference counter and free if needed */
+void siri_fp_decref(siri_fp_t * fp);
+void siri_fp_close(siri_fp_t * fp);
-typedef struct siri_fp_s
+struct siri_fp_s
{
FILE * fp;
uint8_t ref;
-} siri_fp_t;
+};
-
-siri_fp_t * siri_fp_new(void);
-/* closes the file pointer, decrement reference counter and free if needed */
-void siri_fp_decref(siri_fp_t * fp);
-void siri_fp_close(siri_fp_t * fp);
+#endif /* SIRI_FP_H_ */
* - initial version, 15-04-2016
*
*/
-#pragma once
+#ifndef SIRI_GRAMP_H_
+#define SIRI_GRAMP_H_
#include <siri/grammar/grammar.h>
/* help statements */
#define HELP_OFFSET CLERI_GID_HELP_ACCESS
#define HELP_COUNT CLERI_GID_HELP_TIMEZONES + 1 - HELP_OFFSET
+
+#endif /* SIRI_GRAMP_H_ */
* - initial version, 17-06-2016
*
*/
-#pragma once
+#ifndef SIRI_HEARTBEAT_H_
+#define SIRI_HEARTBEAT_H_
#include <siri/siri.h>
-typedef struct siri_s siri_t;
-
void siri_heartbeat_init(siri_t * siri);
void siri_heartbeat_stop(siri_t * siri);
void siri_heartbeat_force(void);
+
+#endif /* SIRI_HEARTBEAT_H_ */
* - initial version, 23-09-2016
*
*/
-#pragma once
+#ifndef SIRI_HELP_H_
+#define SIRI_HELP_H_
#include <siri/grammar/gramp.h>
char * err_msg);
void siri_help_free(void);
+
+#endif /* SIRI_HELP_H_ */
* - initial version, 18-06-2016
*
*/
-#pragma once
+#ifndef SIRINET_BSERVER_H_
+#define SIRINET_BSERVER_H_
#include <siri/siri.h>
int sirinet_bserver_init(siri_t * siri);
+
+#endif /* SIRINET_BSERVER_H_ */
* - initial version, 09-03-2016
*
*/
-#pragma once
+#ifndef SIRINET_CLSERVER_H_
+#define SIRINET_CLSERVER_H_
#include <uv.h>
-#include <siri/net/pipe.h>
-#include <siri/net/socket.h>
#include <siri/siri.h>
-typedef struct siri_s siri_t;
-
-#define sirinet_client_incref(client) \
-switch ((client)->type) \
-{ \
-case UV_TCP: \
- sirinet_socket_incref(client); \
- break; \
-case UV_NAMED_PIPE: \
- sirinet_pipe_incref(client); \
- break; \
-default: \
- break; \
-}
-
-#define sirinet_client_decref(client) \
-switch ((client)->type) \
-{ \
-case UV_TCP: \
- sirinet_socket_decref(client); \
- break; \
-case UV_NAMED_PIPE: \
- sirinet_pipe_decref(client); \
- break; \
-default: \
- uv_close((uv_handle_t *) (client), NULL); \
- break; \
-}
-
-#define CLIENT_SIRIDB(client, siridb) \
-siridb_t * siridb = NULL; \
-switch ((client)->type) \
-{ \
-case UV_TCP: \
- siridb = ((sirinet_socket_t *) (client)->data)->siridb; \
- break; \
-case UV_NAMED_PIPE: \
- siridb = ((sirinet_pipe_t *) (client)->data)->siridb; \
- break; \
-default: \
- break; \
-}
-
-#define CLIENT_USER(client, user) \
-siridb_user_t * user = NULL; \
-switch ((client)->type) \
-{ \
-case UV_TCP: \
- user = (siridb_user_t *) ((sirinet_socket_t *) (client)->data)->origin; \
- break; \
-case UV_NAMED_PIPE: \
- user = (siridb_user_t *) ((sirinet_pipe_t *) (client)->data)->origin; \
- break; \
-default: \
- break; \
-}
+typedef ssize_t (*sirinet_clserver_getfile)(char ** buffer, siridb_t * siridb);
int sirinet_clserver_init(siri_t * siri);
-typedef ssize_t (*sirinet_clserver_getfile)(char ** buffer, siridb_t * siridb);
+#endif /* SIRINET_CLSERVER_H_ */
-#pragma once
+#ifndef SIRINET_PIPE_H_
+#define SIRINET_PIPE_H_
#include <uv.h>
-#include <siri/db/db.h>
-#include <siri/net/pkg.h>
-#include <xpath/xpath.h>
-#define PIPE_NAME_SZ SIRI_PATH_MAX
-#define RESET_BUF_SIZE 1048576 /* 1 MB */
+char * sirinet_pipe_name(uv_pipe_t * client);
-typedef enum sirinet_pipe_tp
-{
- PIPE_CLIENT,
- PIPE_BACKEND
-} sirinet_pipe_tp_t;
-
-typedef struct siridb_s siridb_t;
-typedef struct siridb_user_s siridb_user_t;
-
-typedef void (* on_data_cb_t)(uv_stream_t * client, sirinet_pkg_t * pkg);
-typedef void (* on_free_cb_t)(uv_stream_t * client);
-
-typedef struct sirinet_pipe_s
-{
- sirinet_pipe_tp_t tp;
- uint32_t ref;
- on_data_cb_t on_data;
- on_free_cb_t on_free;
- siridb_t * siridb;
- void * origin; /* can be a user, server or NULL */
- char * buf;
- size_t len;
- size_t size;
- uv_pipe_t pipe;
-} sirinet_pipe_t;
-
-uv_pipe_t * sirinet_pipe_new(
- sirinet_pipe_tp_t tp,
- on_data_cb_t cb_data,
- on_free_cb_t cb_free);
-void sirinet_pipe_alloc_buffer(
- uv_handle_t * handle,
- size_t suggested_size,
- uv_buf_t * buf);
-int sirinet_pipe_name(char * buffer, uv_stream_t * client);
-void sirinet_pipe_on_data(
- uv_stream_t * client,
- ssize_t nread,
- const uv_buf_t * buf);
-void sirinet__pipe_free(uv_stream_t * client);
-
-#define sirinet_pipe_incref(client) \
- ((sirinet_pipe_t *) client->data)->ref++
-
-#define sirinet_pipe_decref(client) \
- if (!--((sirinet_pipe_t *) client->data)->ref) \
- uv_close((uv_handle_t *) client, (uv_close_cb) sirinet__pipe_free)
+#endif /* SIRINET_PIPE_H_ */
* - initial version, 18-06-2016
*
*/
-#pragma once
+#ifndef SIRINET_PKG_H_
+#define SIRINET_PKG_H_
+
+typedef struct sirinet_pkg_s sirinet_pkg_t;
#include <inttypes.h>
#include <qpack/qpack.h>
+#include <siri/net/stream.h>
#include <uv.h>
-typedef struct sirinet_pkg_s
-{
- uint32_t len; /* length of data, sizeof(sirinet_pkg_t) is not included */
- uint16_t pid;
- uint8_t tp;
- uint8_t checkbit;
- unsigned char data[];
-} sirinet_pkg_t;
-
sirinet_pkg_t * sirinet_pkg_new(
uint16_t pid,
uint32_t len,
uint8_t tp,
const char * msg);
-int sirinet_pkg_send(uv_stream_t * client, sirinet_pkg_t * pkg);
+int sirinet_pkg_send(sirinet_stream_t * client, sirinet_pkg_t * pkg);
sirinet_pkg_t * sirinet_pkg_dup(sirinet_pkg_t * pkg);
/* Shortcut to print an packer object */
#define sn_packer_print(packer) \
qp_print(packer->buffer + sizeof(sirinet_pkg_t), packer->len - sizeof(sirinet_pkg_t))
+
+struct sirinet_pkg_s
+{
+ uint32_t len; /* length of data, sizeof(sirinet_pkg_t) is not included */
+ uint16_t pid;
+ uint8_t tp;
+ uint8_t checkbit;
+ unsigned char data[];
+};
+
+#endif /* SIRINET_PKG_H_ */
* - initial version, 21-06-2016
*
*/
-#pragma once
-
-#include <uv.h>
-#include <siri/net/socket.h>
-#include <siri/db/server.h>
-#include <siri/net/pkg.h>
+#ifndef SIRINET_PROMISE_H_
+#define SIRINET_PROMISE_H_
#define PROMISE_DEFAULT_TIMEOUT 30000 /* 30 seconds */
-typedef struct siridb_server_s siridb_server_t;
-typedef struct sirinet_promise_s sirinet_promise_t;
-
typedef enum
{
PROMISE_TIMEOUT_ERROR=-4, /* in case of a time out */
PROMISE_SUCCESS=0
} sirinet_promise_status_t;
+typedef struct sirinet_promise_s sirinet_promise_t;
+
+typedef struct sirinet_pkg_s sirinet_pkg_t;
typedef void (* sirinet_promise_cb)(
sirinet_promise_t * promise,
sirinet_pkg_t * pkg,
int status);
+#include <uv.h>
+#include <siri/net/stream.h>
+#include <siri/db/server.h>
+#include <siri/net/pkg.h>
+
+
+
+const char * sirinet_promise_strstatus(sirinet_promise_status_t status);
+
+#define sirinet_promise_incref(promise) promise->ref++
+#define sirinet_promise_decref(promise) if (!--promise->ref) free(promise)
+
/* the callback will always be called and is responsible to free the promise */
-typedef struct sirinet_promise_s
+struct sirinet_promise_s
{
uint16_t pid;
uint16_t ref;
siridb_server_t * server;
sirinet_pkg_t * pkg;
void * data;
-} sirinet_promise_t;
-
-const char * sirinet_promise_strstatus(sirinet_promise_status_t status);
+};
-#define sirinet_promise_incref(promise) promise->ref++
-#define sirinet_promise_decref(promise) if (!--promise->ref) free(promise)
+#endif /* SIRINET_PROMISE_H_ */
* - initial version, 13-07-2016
*
*/
-#pragma once
-#include <siri/net/promise.h>
-#include <slist/slist.h>
-#include <siri/net/pkg.h>
+#ifndef SIRINET_PROMISES_H_
+#define SIRINET_PROMISES_H_
+typedef struct sirinet_promises_s sirinet_promises_t;
-typedef struct sirinet_promise_s sirinet_promise_t;
-
+#include <slist/slist.h>
typedef void (* sirinet_promises_cb)(
slist_t * promises,
void * data);
-typedef struct sirinet_promises_s
-{
- sirinet_promises_cb cb;
- slist_t * promises;
- void * data;
- sirinet_pkg_t * pkg;
-} sirinet_promises_t;
+#include <siri/net/promise.h>
+#include <siri/net/pkg.h>
sirinet_promises_t * sirinet_promises_new(
size_t size,
slist_free(promises->promises); \
free(promises); \
}
+
+struct sirinet_promises_s
+{
+ sirinet_promises_cb cb;
+ slist_t * promises;
+ void * data;
+ sirinet_pkg_t * pkg;
+};
+
+#endif /* SIRINET_PROMISES_H_ */
* - initial version, 17-03-2016
*
*/
-#pragma once
+#ifndef SIRINET_PROTOCOL_H_
+#define SIRINET_PROTOCOL_H_
typedef enum
{
- CPROTO_REQ_QUERY, /* (query, time_precision) */
- CPROTO_REQ_INSERT, /* series with points map/array */
- CPROTO_REQ_AUTH, /* (user, password, dbname) */
- CPROTO_REQ_PING, /* empty */
- CPROTO_REQ_INFO, /* empty */
- CPROTO_REQ_LOADDB, /* database path */
- CPROTO_REQ_REGISTER_SERVER, /* (uuid, host, port, pool) */
- CPROTO_REQ_FILE_SERVERS, /* empty */
- CPROTO_REQ_FILE_USERS, /* empty */
- CPROTO_REQ_FILE_GROUPS, /* empty */
- CPROTO_REQ_FILE_DATABASE, /* empty */
- /* Administrative API request */
+ /* Public requests */
+ CPROTO_REQ_QUERY=0, /* (query, time_precision) */
+ CPROTO_REQ_INSERT=1, /* series with points map/array */
+ CPROTO_REQ_AUTH=2, /* (user, password, dbname) */
+ CPROTO_REQ_PING=3, /* empty */
+
+ /* Internal usage only */
+ CPROTO_REQ_REGISTER_SERVER=6, /* (uuid, host, port, pool) */
+ CPROTO_REQ_FILE_SERVERS=7, /* empty */
+ CPROTO_REQ_FILE_USERS=8, /* empty */
+ CPROTO_REQ_FILE_GROUPS=9, /* empty */
+ CPROTO_REQ_FILE_DATABASE=10, /* empty */
+
+ /* Public Administrative API request */
CPROTO_REQ_ADMIN=32, /* (user, password, request, {...}) */
} cproto_client_t;
typedef enum
{
/* success */
- CPROTO_RES_QUERY, /* {query response data} */
- CPROTO_RES_INSERT, /* {"success_msg": ...} */
- CPROTO_RES_AUTH_SUCCESS, /* empty */
- CPROTO_RES_ACK, /* empty */
- CPROTO_RES_INFO, /* [version, [dnname1, ...]] */
- CPROTO_RES_FILE, /* file content */
+ CPROTO_RES_QUERY=0, /* {query response data} */
+ CPROTO_RES_INSERT=1, /* {"success_msg": ...} */
+ CPROTO_RES_AUTH_SUCCESS=2, /* empty */
+ CPROTO_RES_ACK=3, /* empty */
+ CPROTO_RES_FILE=5, /* file content */
/* Administrative API success */
CPROTO_ACK_ADMIN=32, /* empty */
/* errors 64-69 are errors with messages */
CPROTO_ERR_MSG=64, /* {"error_msg": ...} */
- CPROTO_ERR_QUERY, /* {"error_msg": ...} */
- CPROTO_ERR_INSERT, /* {"error_msg": ...} */
- CPROTO_ERR_SERVER, /* {"error_msg": ...} */
- CPROTO_ERR_POOL, /* {"error_msg": ...} */
- CPROTO_ERR_USER_ACCESS, /* {"error_msg": ...} */
- CPROTO_ERR, /* empty (use for unexpected errors)*/
- CPROTO_ERR_NOT_AUTHENTICATED, /* empty */
- CPROTO_ERR_AUTH_CREDENTIALS, /* empty */
- CPROTO_ERR_AUTH_UNKNOWN_DB, /* empty */
- CPROTO_ERR_LOADING_DB, /* empty */
- CPROTO_ERR_FILE, /* empty */
+ CPROTO_ERR_QUERY=65, /* {"error_msg": ...} */
+ CPROTO_ERR_INSERT=66, /* {"error_msg": ...} */
+ CPROTO_ERR_SERVER=67, /* {"error_msg": ...} */
+ CPROTO_ERR_POOL=68, /* {"error_msg": ...} */
+ CPROTO_ERR_USER_ACCESS=69, /* {"error_msg": ...} */
+ CPROTO_ERR=70, /* empty (use for unexpected errors)*/
+ CPROTO_ERR_NOT_AUTHENTICATED=71, /* empty */
+ CPROTO_ERR_AUTH_CREDENTIALS=72, /* empty */
+ CPROTO_ERR_AUTH_UNKNOWN_DB=73, /* empty */
+ CPROTO_ERR_FILE=75, /* empty */
/* Administrative API errors */
CPROTO_ERR_ADMIN=96, /* {"error_msg": ...} */
- CPROTO_ERR_ADMIN_INVALID_REQUEST, /* empty */
+ CPROTO_ERR_ADMIN_INVALID_REQUEST=97,/* empty */
CPROTO_DEFERRED=127 /* deferred... */
} cproto_server_t;
const char * sirinet_cproto_server_str(cproto_server_t n);
const char * sirinet_bproto_client_str(bproto_client_t n);
const char * sirinet_bproto_server_str(bproto_server_t n);
+
+#endif /* SIRINET_PROTOCOL_H_ */
+++ /dev/null
-/*
- * socket.h - Handle TCP request.
- *
- * author : Jeroen van der Heijden
- * email : jeroen@transceptor.technology
- * copyright : 2016, Transceptor Technology
- *
- * changes
- * - initial version, 09-03-2016
- *
- */
-#pragma once
-
-#include <uv.h>
-#include <siri/db/db.h>
-#include <siri/net/pkg.h>
-
-#define ADDR_BUF_SZ 54
-#define RESET_BUF_SIZE 1048576 /* 1 MB */
-
-/* Warning: do not change the order! (maps to dns_req_family_map) */
-enum
-{
- IP_SUPPORT_ALL,
- IP_SUPPORT_IPV4ONLY,
- IP_SUPPORT_IPV6ONLY
-};
-
-typedef enum sirinet_socket_tp
-{
- SOCKET_CLIENT,
- SOCKET_BACKEND,
- SOCKET_SERVER,
- SOCKET_MANAGE
-} sirinet_socket_tp_t;
-
-typedef struct siridb_s siridb_t;
-typedef struct siridb_user_s siridb_user_t;
-
-typedef void (* on_data_cb_t)(uv_stream_t * client, sirinet_pkg_t * pkg);
-
-typedef struct sirinet_socket_s
-{
- sirinet_socket_tp_t tp;
- uint32_t ref;
- on_data_cb_t on_data;
- siridb_t * siridb;
- void * origin; /* can be a user, server or NULL */
- char * buf;
- size_t len;
- size_t size;
- uv_tcp_t tcp;
-} sirinet_socket_t;
-
-int dns_req_family_map[3];
-
-const char * sirinet_socket_ip_support_str(uint8_t ip_support);
-uv_tcp_t * sirinet_socket_new(sirinet_socket_tp_t tp, on_data_cb_t cb);
-void sirinet_socket_alloc_buffer(
- uv_handle_t * handle,
- size_t suggested_size,
- uv_buf_t * buf);
-int sirinet_addr_and_port(char * buffer, uv_stream_t * client);
-void sirinet_socket_on_data(
- uv_stream_t * client,
- ssize_t nread,
- const uv_buf_t * buf);
-void sirinet__socket_free(uv_stream_t * client);
-
-#define sirinet_socket_incref(client) \
- ((sirinet_socket_t *) client->data)->ref++
-
-#define sirinet_socket_decref(client) \
- if (!--((sirinet_socket_t *) client->data)->ref) \
- uv_close((uv_handle_t *) client, (uv_close_cb) sirinet__socket_free)
--- /dev/null
+/*
+ * stream.h - Streams, used for uv_tcp_t and uv_pipe_t.
+ *
+ * author : Jeroen van der Heijden
+ * email : jeroen@transceptor.technology
+ * copyright : 2018, Transceptor Technology
+ *
+ * changes
+ * - initial version, 22-08-2018
+ *
+ */
+#ifndef SIRINET_STREAM_H_
+#define SIRINET_STREAM_H_
+
+#define RESET_BUF_SIZE 1048576 /* 1 MB */
+
+typedef enum
+{
+ STREAM_TCP_CLIENT,
+ STREAM_TCP_BACKEND,
+ STREAM_TCP_SERVER,
+ STREAM_TCP_MANAGE,
+ STREAM_PIPE_CLIENT,
+} sirinet_stream_tp_t;
+
+typedef struct sirinet_stream_s sirinet_stream_t;
+
+#include <uv.h>
+#include <siri/db/db.h>
+#include <siri/net/pkg.h>
+
+typedef void (* on_data_cb_t)(sirinet_stream_t * stream, sirinet_pkg_t * pkg);
+
+sirinet_stream_t * sirinet_stream_new(sirinet_stream_tp_t tp, on_data_cb_t cb);
+char * sirinet_stream_name(sirinet_stream_t * client);
+void sirinet_stream_alloc_buffer(
+ uv_handle_t * handle,
+ size_t suggested_size,
+ uv_buf_t * buf);
+void sirinet_stream_on_data(
+ uv_stream_t * client,
+ ssize_t nread,
+ const uv_buf_t * buf);
+void sirinet__stream_free(uv_stream_t * uvclient);
+
+#define sirinet_stream_incref(client) \
+ (client)->ref++
+
+#define sirinet_stream_decref(client) \
+ if (!--(client)->ref) uv_close( \
+ (uv_handle_t *) (client)->stream, \
+ (uv_close_cb) sirinet__stream_free)
+
+#define sirinet_stream_is_pipe(client) \
+ ((client)->tp == STREAM_PIPE_CLIENT)
+
+struct sirinet_stream_s
+{
+ sirinet_stream_tp_t tp;
+ uint32_t ref;
+ on_data_cb_t on_data;
+ siridb_t * siridb;
+ void * origin; /* can be a user, server or NULL */
+ char * buf;
+ size_t len;
+ size_t size;
+ uv_stream_t * stream;
+};
+
+#endif /* SIRINET_STREAM_H_ */
--- /dev/null
+/*
+ * tcp.h
+ *
+ * author : Jeroen van der Heijden
+ * email : jeroen@transceptor.technology
+ * copyright : 2018, Transceptor Technology
+ *
+ * changes
+ * - initial version, 22-08-2018
+ *
+ */
+#ifndef SIRINET_TCP_H_
+#define SIRINET_TCP_H_
+
+#include <uv.h>
+
+/* Warning: do not change the order! (maps to dns_req_family_map) */
+enum
+{
+ IP_SUPPORT_ALL,
+ IP_SUPPORT_IPV4ONLY,
+ IP_SUPPORT_IPV6ONLY
+};
+
+int dns_req_family_map[3];
+const char * sirinet_tcp_ip_support_str(uint8_t ip_support);
+char * sirinet_tcp_name(uv_tcp_t * client);
+
+#endif /* SIRINET_TCP_H_ */
* - initial version, 09-05-2016
*
*/
-#pragma once
-
-#include <uv.h>
-#include <siri/siri.h>
-#include <stdio.h>
+#ifndef SIRI_OPTIMIZE_H_
+#define SIRI_OPTIMIZE_H_
#define SIRI_OPTIMIZE_PENDING 0
#define SIRI_OPTIMIZE_RUNNING 1
#define SIRI_OPTIMIZE_PAUSED 3 /* only set in 'siri_optimize_wait' */
#define SIRI_OPTIMIZE_PAUSED_MAIN 4
-typedef struct siri_s siri_t;
+typedef struct siri_optimize_s siri_optimize_t;
-typedef struct siri_optimize_s
-{
- uv_timer_t timer;
- int status;
- time_t start;
- uv_work_t work;
- uint16_t pause;
- FILE * idx_fp;
- char * idx_fn;
-} siri_optimize_t;
+#define SIRI_OPTIMZE_IS_PAUSED (siri.optimize->status >= SIRI_OPTIMIZE_PAUSED)
+
+#include <uv.h>
+#include <stdio.h>
+#include <siri/siri.h>
void siri_optimize_init(siri_t * siri);
void siri_optimize_stop(void);
int siri_optimize_create_idx(const char * fn);
int siri_optimize_finish_idx(const char * fn, int remove_old);
-#define SIRI_OPTIMZE_IS_PAUSED (siri.optimize->status >= SIRI_OPTIMIZE_PAUSED)
+struct siri_optimize_s
+{
+ uv_timer_t timer;
+ int status;
+ time_t start;
+ uv_work_t work;
+ uint16_t pause;
+ FILE * idx_fp;
+ char * idx_fn;
+};
+#endif /* SIRI_OPTIMIZE_H_ */
+++ /dev/null
-/*
- * listener.h - contains functions for processing queries.
- *
- * author : Jeroen van der Heijden
- * email : jeroen@transceptor.technology
- * copyright : 2016, Transceptor Technology
- *
- * changes
- * - initial version, 10-03-2016
- *
- */
-#pragma once
-
-#include <uv.h>
-#include <siri/grammar/grammar.h>
-
-uv_async_cb siriparser_listen_enter[CLERI_END];
-uv_async_cb siriparser_listen_exit[CLERI_END];
-
-void siriparser_init_listener(void);
+++ /dev/null
-/*
- * queries.h - Querie helpers for listener
- *
- * author : Jeroen van der Heijden
- * email : jeroen@transceptor.technology
- * copyright : 2016, Transceptor Technology
- *
- * changes
- * - initial version, 03-05-2016
- *
- */
-#pragma once
-
-#include <uv.h>
-#include <inttypes.h>
-#include <imap/imap.h>
-#include <slist/slist.h>
-#include <cexpr/cexpr.h>
-#include <cleri/cleri.h>
-#include <ctree/ctree.h>
-#include <siri/db/presuf.h>
-#include <siri/db/group.h>
-#include <siri/db/series.h>
-#include <siri/db/user.h>
-#include <pcre2.h>
-
-#define QUERIES_IGNORE_DROP_THRESHOLD 1
-#define QUERIES_SKIP_GET_POINTS 2
-
-enum
-{
- QUERIES_ALTER,
- QUERIES_COUNT,
- QUERIES_DROP,
- QUERIES_LIST,
- QUERIES_SELECT
-};
-
-typedef enum
-{
- QUERY_ALTER_NONE,
- QUERY_ALTER_DATABASE,
- QUERY_ALTER_GROUP,
- QUERY_ALTER_SERVER,
- QUERY_ALTER_SERVERS,
- QUERY_ALTER_USER
-} query_alter_tp;
-
-#define QUERY_DEF \
-uint8_t tp; \
-uint8_t flags; \
-imap_t * series_map; \
-imap_t * series_tmp; \
-imap_t * pmap; \
-slist_t * slist; \
-size_t slist_index; \
-imap_update_cb update_cb; \
-cexpr_t * where_expr; \
-pcre2_code * regex; \
-pcre2_match_data * match_data;
-
-
-/* wrappers */
-typedef struct query_wrapper_s
-{
- QUERY_DEF
-} query_wrapper_t;
-
-union query_alter_u
-{
- siridb_group_t * group;
- siridb_server_t * server;
- siridb_user_t * user;
- void * dummy;
-};
-
-typedef struct query_alter_s
-{
- QUERY_DEF
- query_alter_tp alter_tp;
- union query_alter_u via;
- size_t n; /* can be used as counter */
-} query_alter_t;
-
-typedef struct query_count_s
-{
- QUERY_DEF
- size_t n; /* can be used as counter */
-} query_count_t;
-
-typedef struct query_drop_s
-{
- QUERY_DEF
- size_t n; /* keep a counter for number of drops. */
- slist_t * shards_list;
-} query_drop_t;
-
-typedef struct query_list_s
-{
- QUERY_DEF
- slist_t * props; /* will be freed */
- size_t limit;
-} query_list_t;
-
-typedef struct query_select_s
-{
- QUERY_DEF
- size_t n;
- size_t nselects;
- uint64_t * start_ts; /* will NOT be freed */
- uint64_t * end_ts; /* will NOT be freed */
- siridb_presuf_t * presuf;
- char * merge_as;
- ct_t * result;
- imap_t * points_map; /* points_map for caching */
- slist_t * alist; /* aggregation list (can be used multiple times)*/
- slist_t * mlist; /* merge aggregation list */
-} query_select_t;
-
-query_alter_t * query_alter_new(void);
-void query_alter_free(uv_handle_t * handle);
-
-query_count_t * query_count_new(void);
-void query_count_free(uv_handle_t * handle);
-
-query_drop_t * query_drop_new(void);
-void query_drop_free(uv_handle_t * handle);
-
-query_list_t * query_list_new(void);
-void query_list_free(uv_handle_t * handle);
-
-query_select_t * query_select_new(void);
-void query_select_free(uv_handle_t * handle);
-
-void query_help_free(uv_handle_t * handle);
* - initial version, 08-03-2016
*
*/
-#pragma once
+#ifndef SIRI_H_
+#define SIRI_H_
#define PCRE2_CODE_UNIT_WIDTH 8
+#define SIRI_MAX_SIZE_ERR_MSG 1024
+#define SIRIDB_BUILD_DATE __DATE__ " " __TIME__
+#define MAX_NUMBER_DB 4
+
+typedef enum
+{
+ SIRI_STATUS_LOADING,
+ SIRI_STATUS_RUNNING,
+ SIRI_STATUS_CLOSING
+} siri_status_t;
+
+typedef struct siri_s siri_t;
+
+extern siri_t siri;
+
#include <uv.h>
#include <pcre2.h>
#include <siri/grammar/grammar.h>
#include <siri/args/args.h>
#include <llist/llist.h>
-#define SIRI_MAX_SIZE_ERR_MSG 1024
-#define SIRIDB_BUILD_DATE __DATE__ " " __TIME__
-#define MAX_NUMBER_DB 4
-
-typedef struct cleri_grammar_s cleri_grammar_t;
-typedef struct siridb_list_s siridb_list_t;
-typedef struct siri_fh_s siri_fh_t;
-typedef struct siri_optimize_s siri_optimize_t;
-typedef struct siri_heartbeat_s siri_heartbeat_t;
-typedef struct siri_backup_s siri_backup_t;
-typedef struct siri_cfg_s siri_cfg_t;
-typedef struct siri_args_s siri_args_t;
-typedef struct llist_s llist_t;
-
-typedef enum
-{
- SIRI_STATUS_LOADING,
- SIRI_STATUS_RUNNING,
- SIRI_STATUS_CLOSING
-} siri_status_t;
+void siri_setup_logger(void);
+int siri_start(void);
+void siri_free(void);
-typedef struct siri_s
+struct siri_s
{
siri_status_t status;
uv_loop_t * loop;
pcre2_match_data * dbname_match_data;
/* socket and promises used for expanding (client) */
- uv_tcp_t * socket;
+ sirinet_stream_t * client;
uv_timer_t timer;
-} siri_t;
-
-void siri_setup_logger(void);
-int siri_start(void);
-void siri_free(void);
+};
-extern siri_t siri;
+#endif /* SIRI_H_ */
* - initial version, 08-03-2016
*
*/
-#pragma once
+#ifndef SIRI_VERSION_H_
+#define SIRI_VERSION_H_
#define SIRIDB_VERSION_MAJOR 2
#define SIRIDB_VERSION_MINOR 0
/* SiriDB can only connect with servers having at least this version. */
#define SIRIDB_MINIMAL_VERSION "2.0.0"
+
+#endif /* SIRI_VERSION_H_ */
* - initial version, 06-06-2016
*
*/
-#pragma once
+#ifndef SLIST_H_
+#define SLIST_H_
#define SLIST_DEFAULT_SIZE 8
#include <stddef.h>
#include <inttypes.h>
-struct slist_object_s
-{
- uint32_t ref;
-};
-
-struct slist_s
-{
- size_t size;
- size_t len;
- void * data[];
-};
-
slist_t * slist_new(size_t size);
slist_t * slist_copy(slist_t * source);
void slist_compact(slist_t ** slist);
* Pop the last item from the list
*/
#define slist_pop(slist) slist->data[--slist->len]
+
+struct slist_object_s
+{
+ uint32_t ref;
+};
+
+struct slist_s
+{
+ size_t size;
+ size_t len;
+ void * data[];
+};
+
+#endif /* SLIST_H_ */
* - initial version, 19-03-2016
*
*/
-#pragma once
+#ifndef STREXTRA_H_
+#define STREXTRA_H_
#include <stdbool.h>
#include <stddef.h>
/* important: 'dest' needs to be freed */
size_t strx_extract_string(char * dest, const char * source, size_t len);
+
+#endif /* STREXTRA_H_ */
* - initial version, 13-03-2016
*
*/
-#pragma once
+#ifndef SIRIDB_TEST_H_
+#define SIRIDB_TEST_H_
int run_tests(void);
+
+#endif /* SIRIDB_TEST_H_ */
* - initial version, 16-03-2016
*
*/
-#pragma once
+#ifndef TIMEIT_H_
+#define TIMEIT_H_
#include <time.h>
*
* log_debug("Time in milliseconds: %f",timeit_stop(&start));
*/
+
+#endif /* TIMEIT_H_ */
* - initial version, 12-03-2016
*
*/
-#pragma once
+#ifndef XMATH_H_
+#define XMATH_H_
#include <inttypes.h>
#include <stddef.h>
uint32_t xmath_ipow(int base, int exp);
size_t xmath_max_size(size_t n, ...);
+
+#endif /* XMATH_H_ */
* - initial version, 15-07-2016
*
*/
-#pragma once
+#ifndef XPATH_H_
+#define XPATH_H_
#include <stdio.h>
#include <limits.h>
int xpath_is_dir(const char * path);
ssize_t xpath_get_content(char ** buffer, const char * fn);
int xpath_get_exec_path(char * path);
+
+#endif /* XPATH_H_ */
cfgparser_section_t * section,
const char * name,
cfgparser_tp_t tp,
- cfgparser_u * val,
- cfgparser_u * def);
+ cfgparser_via_t * val,
+ cfgparser_via_t * def);
#define MAXLINE 255
const char * val,
const char * def)
{
- cfgparser_u * val_u = (cfgparser_u *) malloc(sizeof(cfgparser_u));
- cfgparser_u * def_u = (cfgparser_u *) malloc(sizeof(cfgparser_u));
+ cfgparser_via_t * val_u = (cfgparser_via_t *) malloc(sizeof(cfgparser_via_t));
+ cfgparser_via_t * def_u = (cfgparser_via_t *) malloc(sizeof(cfgparser_via_t));
if (val_u == NULL || def_u == NULL)
{
int32_t val,
int32_t def)
{
- cfgparser_u * val_u = (cfgparser_u *) malloc(sizeof(cfgparser_u));
- cfgparser_u * def_u = (cfgparser_u *) malloc(sizeof(cfgparser_u));
+ cfgparser_via_t * val_u = (cfgparser_via_t *) malloc(sizeof(cfgparser_via_t));
+ cfgparser_via_t * def_u = (cfgparser_via_t *) malloc(sizeof(cfgparser_via_t));
if (val_u == NULL || def_u == NULL)
{
ERR_ALLOC
double val,
double def)
{
- cfgparser_u * val_u = (cfgparser_u *) malloc(sizeof(cfgparser_u));
- cfgparser_u * def_u = (cfgparser_u *) malloc(sizeof(cfgparser_u));
+ cfgparser_via_t * val_u = (cfgparser_via_t *) malloc(sizeof(cfgparser_via_t));
+ cfgparser_via_t * def_u = (cfgparser_via_t *) malloc(sizeof(cfgparser_via_t));
if (val_u == NULL || def_u == NULL)
{
ERR_ALLOC
cfgparser_section_t * section,
const char * name,
cfgparser_tp_t tp,
- cfgparser_u * val,
- cfgparser_u * def)
+ cfgparser_via_t * val,
+ cfgparser_via_t * def)
{
cfgparser_option_t * current = section->options;
cfgparser_option_t * prev;
* - initial version, 24-03-2017
*
*/
-#include <siri/admin/client.h>
-#include <siri/siri.h>
-#include <logger/logger.h>
-#include <siri/net/socket.h>
#include <string.h>
-#include <siri/net/protocol.h>
-#include <siri/admin/request.h>
#include <stdarg.h>
#include <lock/lock.h>
-#include <siri/db/server.h>
+#include <logger/logger.h>
+#include <siri/siri.h>
#include <siri/version.h>
+#include <siri/admin/client.h>
+#include <siri/admin/request.h>
+#include <siri/net/stream.h>
+#include <siri/net/protocol.h>
+#include <siri/net/tcp.h>
+#include <siri/db/server.h>
/* 15 seconds */
#define CLIENT_REQUEST_TIMEOUT 15000
static void CLIENT_write_cb(uv_write_t * req, int status);
static void CLIENT_on_connect(uv_connect_t * req, int status);
-static void CLIENT_on_data(uv_stream_t * client, sirinet_pkg_t * pkg);
+static void CLIENT_on_data(sirinet_stream_t * client, sirinet_pkg_t * pkg);
static void CLIENT_request_timeout(uv_timer_t * handle);
static void CLIENT_on_auth_success(siri_admin_client_t * adm_client);
static int CLIENT_resolve_dns(
qp_obj_t * password,
qp_obj_t * dbname,
const char * dbpath,
- uv_stream_t * client,
+ sirinet_stream_t * client,
char * err_msg)
{
- sirinet_socket_t * ssocket;
siri_admin_client_t * adm_client;
struct in_addr sa;
struct in6_addr sa6;
- if (siri.socket != NULL)
+ if (siri.client != NULL)
{
sprintf(err_msg, "manage socket already in use");
return -1;
}
- siri.socket = sirinet_socket_new(SOCKET_MANAGE, &CLIENT_on_data);
- if (siri.socket == NULL)
+ siri.client = sirinet_stream_new(STREAM_TCP_MANAGE, &CLIENT_on_data);
+ if (siri.client == NULL)
{
sprintf(err_msg, "memory allocation error");
return -1;
}
- uv_tcp_init(siri.loop, siri.socket);
+ uv_tcp_init(siri.loop, (uv_tcp_t *) siri.client->stream);
adm_client = (siri_admin_client_t *) malloc(sizeof(siri_admin_client_t));
if (adm_client == NULL)
{
- sirinet_socket_decref(siri.socket);
+ sirinet_stream_decref(siri.client);
sprintf(err_msg, "memory allocation error");
return -1;
}
adm_client->pool = pool;
memcpy(&adm_client->uuid, uuid, 16);
- ssocket = (sirinet_socket_t *) siri.socket->data;
- ssocket->origin = (void *) adm_client;
- sirinet_socket_incref(adm_client->client);
+ siri.client->origin = (void *) adm_client;
+
+ sirinet_stream_incref(adm_client->client);
if (adm_client->host == NULL ||
adm_client->username == NULL ||
adm_client->dbname == NULL ||
adm_client->dbpath == NULL)
{
- sirinet_socket_decref(siri.socket);
+ sirinet_stream_decref(siri.client);
sprintf(err_msg, "memory allocation error");
return -1;
}
uv_connect_t * req = (uv_connect_t *) malloc(sizeof(uv_connect_t));
if (req == NULL)
{
- sirinet_socket_decref(siri.socket);
+ sirinet_stream_decref(siri.client);
sprintf(err_msg, "memory allocation error");
return -1;
}
uv_ip4_addr(adm_client->host, adm_client->port, &dest);
uv_tcp_connect(
req,
- siri.socket,
+ (uv_tcp_t *) siri.client->stream,
(const struct sockaddr *) &dest,
CLIENT_on_connect);
}
uv_connect_t * req = (uv_connect_t *) malloc(sizeof(uv_connect_t));
if (req == NULL)
{
- sirinet_socket_decref(siri.socket);
+ sirinet_stream_decref(siri.client);
sprintf(err_msg, "memory allocation error");
return -1;
}
uv_ip6_addr(adm_client->host, adm_client->port, &dest6);
uv_tcp_connect(
req,
- siri.socket,
+ (uv_tcp_t *) siri.client->stream,
(const struct sockaddr *) &dest6,
CLIENT_on_connect);
}
dns_req_family_map[siri.cfg->ip_support],
err_msg))
{
- sirinet_socket_decref(siri.socket);
+ sirinet_stream_decref(siri.client);
return -1; /* err_msg is set */
}
}
{
if (adm_client != NULL)
{
- sirinet_socket_decref(adm_client->client);
+ sirinet_stream_decref(adm_client->client);
free(adm_client->host);
free(adm_client->username);
free(adm_client->password);
{
uv_tcp_connect(
req,
- siri.socket,
+ (uv_tcp_t *) siri.client->stream,
(const struct sockaddr *) res->ai_addr,
CLIENT_on_connect);
}
siri_admin_request_rollback(adm_client->dbpath);
}
- sirinet_socket_decref(siri.socket);
+ sirinet_stream_decref(siri.client);
uv_close((uv_handle_t *) &siri.timer, NULL);
}
uv_write(
req,
- (uv_stream_t *) siri.socket,
+ siri.client->stream,
&wrbuf,
1,
CLIENT_write_cb);
*/
static void CLIENT_on_connect(uv_connect_t * req, int status)
{
- sirinet_socket_t * ssocket = req->handle->data;
- siri_admin_client_t * adm_client = (siri_admin_client_t *) ssocket->origin;
+ sirinet_stream_t * client = req->handle->data;
+ siri_admin_client_t * adm_client = client->origin;
if (status == 0)
{
uv_read_start(
req->handle,
- sirinet_socket_alloc_buffer,
- sirinet_socket_on_data);
+ sirinet_stream_alloc_buffer,
+ sirinet_stream_on_data);
sirinet_pkg_t * pkg;
qp_packer_t * packer = sirinet_packer_new(512);
/*
* on-data call-back function.
*/
-static void CLIENT_on_data(uv_stream_t * client, sirinet_pkg_t * pkg)
+static void CLIENT_on_data(sirinet_stream_t * client, sirinet_pkg_t * pkg)
{
- sirinet_socket_t * ssocket = client->data;
- siri_admin_client_t * adm_client = (siri_admin_client_t *) ssocket->origin;
+ siri_admin_client_t * adm_client = client->origin;
log_debug(
"Client response received (pid: %" PRIu16
", len: %" PRIu32 ", tp: %s)",
"Finished registering server on database '%s'",
adm_client->dbname);
- sirinet_socket_decref(siri.socket);
+ sirinet_stream_decref(siri.client);
uv_close((uv_handle_t *) &siri.timer, NULL);
}
static cproto_server_t ADMIN_on_new_replica_or_pool(
qp_unpacker_t * qp_unpacker,
uint16_t pid,
- uv_stream_t * client,
+ sirinet_stream_t * client,
int req,
char * err_msg);
static cproto_server_t ADMIN_on_get_version(
qp_obj_t * qp_account,
qp_packer_t ** packaddr,
uint16_t pid,
- uv_stream_t * client,
+ sirinet_stream_t * client,
char * err_msg)
{
switch ((admin_request_t) tp)
static cproto_server_t ADMIN_on_new_replica_or_pool(
qp_unpacker_t * qp_unpacker,
uint16_t pid,
- uv_stream_t * client,
+ sirinet_stream_t * client,
int req,
char * err_msg)
{
#include <string.h>
#include <unistd.h>
#include <sys/resource.h>
-#include <siri/net/socket.h>
+#include <siri/net/tcp.h>
/* do not use more than x percent for the max limit for open sharding files */
#define RLIMIT_PERC_FOR_SHARDING 0.5
cfgparser_t * cfgparser,
const char * option_name,
char ** dest);
-static void SIRI_CFG_read_pipe_name(
- cfgparser_t * cfgparser,
- const char * option_name,
- char * dest);
+static void SIRI_CFG_read_pipe_client_name(cfgparser_t * cfgparser);
static void SIRI_CFG_read_default_db_path(cfgparser_t * cfgparser);
static void SIRI_CFG_read_max_open_files(cfgparser_t * cfgparser);
static void SIRI_CFG_read_ip_support(cfgparser_t * cfgparser);
if (siri_cfg.pipe_support)
{
- SIRI_CFG_read_pipe_name(
- cfgparser,
- "pipe_client_name",
- &siri_cfg.pipe_client_name);
+ SIRI_CFG_read_pipe_client_name(cfgparser);
}
cfgparser_free(cfgparser);
"ip_support",
siri.args->config,
cfgparser_errmsg(rc),
- sirinet_socket_ip_support_str(siri_cfg.ip_support));
+ sirinet_tcp_ip_support_str(siri_cfg.ip_support));
}
else if (option->tp != CFGPARSER_TP_STRING)
{
"ip_support",
siri.args->config,
"error: expecting a string value",
- sirinet_socket_ip_support_str(siri_cfg.ip_support));
+ sirinet_tcp_ip_support_str(siri_cfg.ip_support));
}
else
{
"ip_support",
siri.args->config,
option->val->string,
- sirinet_socket_ip_support_str(siri_cfg.ip_support));
+ sirinet_tcp_ip_support_str(siri_cfg.ip_support));
}
}
}
{
siri_cfg.shard_compression = 1;
}
-
}
static void SIRI_CFG_read_pipe_support(cfgparser_t * cfgparser)
{
siri_cfg.pipe_support = 1;
}
-
}
static void SIRI_CFG_read_addr(
}
}
-static void SIRI_CFG_read_pipe_name(
- cfgparser_t * cfgparser,
- const char * option_name,
- char * dest)
+static void SIRI_CFG_read_pipe_client_name(cfgparser_t * cfgparser)
{
cfgparser_option_t * option;
cfgparser_return_t rc;
&option,
cfgparser,
"siridb",
- option_name);
+ "pipe_client_name");
if (rc != CFGPARSER_SUCCESS)
{
log_warning(
"Error reading '%s' in '%s': %s. "
"Using default value: '%s'",
- option_name,
+ "pipe_client_name",
siri.args->config,
cfgparser_errmsg(rc),
- dest);
+ siri_cfg.pipe_client_name);
}
else if (option->tp != CFGPARSER_TP_STRING)
{
log_warning(
"Error reading '%s' in '%s': %s. "
"Using default value: '%s'",
- option_name,
+ "pipe_client_name",
siri.args->config,
"error: expecting a string value",
- dest);
+ siri_cfg.pipe_client_name);
}
else
{
- *dest = 0;
-
- /* keep space left for a terminator char */
- strncpy(dest,
- option->val->string,
- SIRI_PATH_MAX - 1);
-
- len = strlen(dest);
-
- if (len == SIRI_PATH_MAX - 1)
+ len = strlen(option->val->string);
+ if (len >= SIRI_PATH_MAX-1)
{
log_warning(
- "Default '%s' path exceeds %d characters, please "
+ "Pipe client name exceeds %d characters, please "
"check your configuration file: %s",
- option_name,
- SIRI_PATH_MAX - 2,
+ SIRI_PATH_MAX-2,
siri.args->config);
}
+ else
+ {
+ strcpy(siri_cfg.pipe_client_name, option->val->string);
+ }
}
}
#include <siri/db/servers.h>
#include <siri/db/users.h>
#include <siri/net/protocol.h>
-#include <siri/net/socket.h>
+#include <siri/net/stream.h>
#include <siri/siri.h>
#include <siri/version.h>
#include <stdlib.h>
#include <string.h>
cproto_server_t siridb_auth_user_request(
- uv_stream_t * client,
+ sirinet_stream_t * client,
qp_obj_t * qp_username,
qp_obj_t * qp_password,
qp_obj_t * qp_dbname)
return CPROTO_ERR_AUTH_CREDENTIALS;
}
- switch (client->type)
- {
- case UV_TCP:
- ((sirinet_socket_t *) client->data)->siridb = siridb;
- ((sirinet_socket_t *) client->data)->origin = user;
- break;
- case UV_NAMED_PIPE:
- ((sirinet_pipe_t *) client->data)->siridb = siridb;
- ((sirinet_pipe_t *) client->data)->origin = user;
- break;
- }
+ client->siridb = siridb;
+ client->origin = user;
siridb_user_incref(user);
* null terminated.
*/
bproto_server_t siridb_auth_server_request(
- uv_stream_t * client,
+ sirinet_stream_t * client,
qp_obj_t * qp_uuid,
qp_obj_t * qp_dbname,
qp_obj_t * qp_version,
return BPROTO_AUTH_ERR_UNKNOWN_UUID;
}
- switch (client->type)
- {
- case UV_TCP:
- ((sirinet_socket_t *) client->data)->siridb = siridb;
- ((sirinet_socket_t *) client->data)->origin = server;
- break;
- case UV_NAMED_PIPE:
- ((sirinet_pipe_t *) client->data)->siridb = siridb;
- ((sirinet_pipe_t *) client->data)->origin = server;
- break;
- }
+ client->siridb = siridb;
+ client->origin = server;
free(server->version);
server->version = strdup((const char *) qp_version->via.raw);
#include <logger/logger.h>
#include <siri/db/buffer.h>
#include <siri/db/db.h>
+#include <siri/db/misc.h>
#include <siri/db/shard.h>
#include <siri/siri.h>
#include <stdio.h>
*/
int siridb_buffer_open(siridb_t * siridb)
{
- SIRIDB_GET_FN(fn, siridb->buffer_path, SIRIDB_BUFFER_FN)
+ siridb_misc_get_fn(fn, siridb->buffer_path, SIRIDB_BUFFER_FN)
if ((siridb->buffer_fp = fopen(fn, "r+")) == NULL)
{
log_info("Loading and cleanup buffer");
- SIRIDB_GET_FN(fn, siridb->buffer_path, SIRIDB_BUFFER_FN)
- SIRIDB_GET_FN(fn_temp, siridb->buffer_path, "__" SIRIDB_BUFFER_FN)
+ siridb_misc_get_fn(fn, siridb->buffer_path, SIRIDB_BUFFER_FN)
+ siridb_misc_get_fn(fn_temp, siridb->buffer_path, "__" SIRIDB_BUFFER_FN)
if (xpath_file_exist(fn_temp))
{
+++ /dev/null
-/*
- * content.c - Log data (string content)
- *
- * author : Jeroen van der Heijden
- * email : jeroen@transceptor.technology
- * copyright : 2017, Transceptor Technology
- *
- * changes
- * - initial version, 11-12-2017
- *
- */
-
-
#include <math.h>
#include <procinfo/procinfo.h>
#include <siri/db/db.h>
+#include <siri/db/misc.h>
#include <siri/db/series.h>
#include <siri/db/servers.h>
#include <siri/db/shard.h>
ssize_t siridb_get_file(char ** buffer, siridb_t * siridb)
{
/* get servers file name */
- SIRIDB_GET_FN(fn, siridb->dbpath, "database.dat")
+ siridb_misc_get_fn(fn, siridb->dbpath, "database.dat")
return xpath_get_content(buffer, fn);
}
siridb_insert_t * siridb_insert_new(
siridb_t * siridb,
uint16_t pid,
- uv_stream_t * client)
+ sirinet_stream_t * client)
{
siridb_insert_t * insert = (siridb_insert_t *) malloc(
sizeof(siridb_insert_t) +
insert->npoints= npoints;
/* increment the client reference counter */
- sirinet_client_incref(insert->client);
+ sirinet_stream_incref(insert->client);
uv_async_init(siri.loop, handle, INSERT_points_to_pools);
handle->data = (void *) insert;
int insert_init_backend_local(
siridb_t * siridb,
- uv_stream_t * client,
+ sirinet_stream_t * client,
sirinet_pkg_t * pkg,
uint8_t flags)
{
}
qp_unpacker_init(&ilocal->unpacker, promise->pkg->data, promise->pkg->len);
- sirinet_client_incref(client);
+ sirinet_stream_incref(client);
promise->data = client;
promise->cb = (sirinet_promise_cb) INSERT_local_promise_backend_cb;
sirinet_pkg_t * pkg;
sirinet_promise_t * promise;
siridb_insert_t * insert = (siridb_insert_t *) handle->data;
- CLIENT_SIRIDB(insert->client, siridb)
+ siridb_t * siridb = insert->client->siridb;
int n = 0;
char msg[MAX_INSERT_MSG];
insert->pid,
tp);
- sirinet_pkg_send((uv_stream_t *) insert->client, response_pkg);
+ sirinet_pkg_send(insert->client, response_pkg);
}
}
#if DEBUG
assert (pkg == NULL);
#endif
- uv_stream_t * client = (uv_stream_t *) promise->data;
+ sirinet_stream_t * client = promise->data;
pkg = sirinet_pkg_new(
promise->pid,
{
sirinet_pkg_send(client, pkg);
}
- sirinet_client_decref(client);
+ sirinet_stream_decref(client);
sirinet_promise_decref(promise);
}
static void INSERT_points_to_pools(uv_async_t * handle)
{
siridb_insert_t * insert = (siridb_insert_t *) handle->data;
- CLIENT_SIRIDB(insert->client, siridb)
+ siridb_t * siridb = insert->client->siridb;
uint16_t pool = siridb->server->pool;
sirinet_pkg_t * pkg, * repl_pkg;
siridb_insert_t * insert = (siridb_insert_t *) handle->data;
/* decrement the client reference counter */
- sirinet_client_decref(insert->client);
+ sirinet_stream_decref(insert->client);
/* free insert */
siridb_insert_free(insert);
--- /dev/null
+/*
+ * listener.c - contains functions for processing queries.
+ *
+ * author : Jeroen van der Heijden
+ * email : jeroen@transceptor.technology
+ * copyright : 2016, Transceptor Technology
+ *
+ * changes
+ * - initial version, 10-03-2016
+ *
+ */
+#include <assert.h>
+#include <cexpr/cexpr.h>
+#include <inttypes.h>
+#include <logger/logger.h>
+#include <qpack/qpack.h>
+#include <siri/async.h>
+#include <siri/db/aggregate.h>
+#include <siri/db/group.h>
+#include <siri/db/groups.h>
+#include <siri/db/nodes.h>
+#include <siri/db/presuf.h>
+#include <siri/db/props.h>
+#include <siri/db/props.h>
+#include <siri/db/query.h>
+#include <siri/db/re.h>
+#include <siri/db/series.h>
+#include <siri/db/server.h>
+#include <siri/db/servers.h>
+#include <siri/db/shard.h>
+#include <siri/db/user.h>
+#include <siri/db/users.h>
+#include <siri/db/listener.h>
+#include <siri/db/queries.h>
+#include <siri/err.h>
+#include <siri/grammar/gramp.h>
+#include <siri/help/help.h>
+#include <siri/net/promises.h>
+#include <siri/net/protocol.h>
+#include <siri/net/clserver.h>
+#include <siri/siri.h>
+#include <strextra/strextra.h>
+#include <sys/time.h>
+
+
+#define MAX_ITERATE_COUNT 10000 /* ten-thousand */
+#define MAX_BATCH_REQUIRE_SHARD 100 /* after reading 100 shards, iterate */
+
+#define QP_ADD_SUCCESS qp_add_raw( \
+ query->packer, (const unsigned char *) "success_msg", 11);
+#define DEFAULT_ALLOC_COLUMNS 6
+#define IS_MASTER (query->flags & SIRIDB_QUERY_FLAG_MASTER)
+
+#define MASTER_CHECK_ONLINE(siridb) \
+if (IS_MASTER && !siridb_server_self_online(siridb->server)) \
+{ \
+ sprintf(query->err_msg, \
+ "Server '%s' is currently not available to process " \
+ "this request", \
+ siridb->server->name); \
+ siridb_query_send_error(handle, CPROTO_ERR_SERVER); \
+ return; \
+} \
+if (IS_MASTER && !siridb_pools_online(siridb)) \
+{ \
+ sprintf(query->err_msg, \
+ "At least one pool is lacking an online server to process " \
+ "this request"); \
+ siridb_query_send_error(handle, CPROTO_ERR_POOL); \
+ return; \
+}
+
+#define MASTER_CHECK_VERSION(siridb, _VERSION) \
+if (IS_MASTER) \
+{ \
+ int nservers = siridb_servers_check_version(siridb, _VERSION); \
+ if (nservers) \
+ { \
+ sprintf(query->err_msg, \
+ "At least %d server%s not running version %s " \
+ "or greater which is required for this query.", \
+ nservers, (nservers == 1) ? " is" : "s are", _VERSION); \
+ siridb_query_send_error(handle, CPROTO_ERR_QUERY); \
+ return; \
+ } \
+}
+
+#define MASTER_CHECK_ACCESSIBLE(siridb) \
+if (IS_MASTER && !siridb_server_self_accessible(siridb->server)) \
+{ \
+ sprintf(query->err_msg, \
+ "Server '%s' is currently not accessible to process " \
+ "this request", \
+ siridb->server->name); \
+ siridb_query_send_error(handle, CPROTO_ERR_SERVER); \
+ return; \
+} \
+if (IS_MASTER && !siridb_pools_accessible(siridb)) \
+{ \
+ sprintf(query->err_msg, \
+ "At least one pool is lacking an accessible server to process " \
+ "this request"); \
+ siridb_query_send_error(handle, CPROTO_ERR_POOL); \
+ return; \
+}
+
+#define MASTER_CHECK_REINDEXING(siridb) \
+if (IS_MASTER && siridb_is_reindexing(siridb)) \
+{ \
+ sprintf(query->err_msg, \
+ "SiriDB cannot perform this request because the database is " \
+ "currently re-indexing"); \
+ siridb_query_send_error(handle, CPROTO_ERR_POOL); \
+ return; \
+}
+
+#define ON_PROMISES \
+ siri_async_decref(&handle); \
+ if (promises == NULL) \
+ { \
+ return; /* signal is raised when handle is NULL */ \
+ } \
+ if (handle == NULL) \
+ { \
+ sirinet_promises_llist_free(promises); \
+ return; /* signal is raised when handle is NULL */ \
+ }
+
+#define MEM_ERR_RET \
+ sprintf(query->err_msg, "Memory allocation error."); \
+ siridb_query_send_error(handle, CPROTO_ERR_QUERY); \
+ return;
+
+#define FILE_ERR_RET \
+ sprintf(query->err_msg, "File error occurred."); \
+ siridb_query_send_error(handle, CPROTO_ERR_QUERY); \
+ return;
+
+#define MSG_SUCCESS_CREATE_USER \
+ "Successfully created user '%s'."
+#define MSG_SUCCESS_DROP_USER \
+ "Successfully dropped user '%s'."
+#define MSG_SUCCESS_ALTER_USER \
+ "Successfully updated user '%s'."
+#define MSG_SUCCESS_GRANT_USER \
+ "Successfully granted permissions to user '%s'."
+#define MSG_SUCCESS_REVOKE_USER \
+ "Successfully revoked permissions from user '%s'."
+#define MSG_SUCCESS_CREATE_GROUP \
+ "Successfully created group '%s'."
+#define MSG_SUCCESS_DROP_GROUP \
+ "Successfully dropped group '%s'."
+#define MSG_SUCCESS_ALTER_GROUP \
+ "Successfully updated group '%s'."
+#define MSG_SUCCESS_SET_DROP_THRESHOLD \
+ "Successfully changed drop_threshold from %g to %g."
+#define MSG_SUCCESS_SET_LIST_LIMIT \
+ "Successfully changed list limit from %" PRIu32 " to %" PRIu32 "."
+#define MSG_SUCCESS_SET_ADDR_PORT \
+ "Successfully changed server address to '%s'."
+#define MSG_SUCCESS_DROP_SERVER \
+ "Successfully dropped server '%s'."
+#define MSG_SUCCES_SET_LOG_LEVEL_MULTI \
+ "Successfully set log level to '%s' on %lu servers."
+#define MSG_SUCCES_SET_LOG_LEVEL \
+ "Successfully set log level to '%s' on '%s'."
+#define MSG_SUCCESS_SET_SELECT_POINTS_LIMIT \
+ "Successfully changed select points limit from %" PRIu32 " to %" PRIu32 "."
+#define MSG_SUCCES_DROP_SERIES \
+ "Successfully dropped %lu series."
+#define MSG_SUCCES_DROP_SHARDS \
+ "Successfully dropped %lu shards. (this number does not include " \
+ "shards which are dropped on replica servers)"
+#define MSG_SUCCES_SET_BACKUP_MODE \
+ "Successfully %s backup mode on '%s'."
+#define MSG_SUCCES_SET_TIMEZONE \
+ "Successfully changed timezone from '%s' to '%s'."
+#define MSG_ERR_SERVER_ADDRESS \
+ "Its only possible to change a servers address or port when the server " \
+ "is not connected."
+
+
+static void enter_access_expr(uv_async_t * handle);
+static void enter_alter_group(uv_async_t * handle);
+static void enter_alter_server(uv_async_t * handle);
+static void enter_alter_servers(uv_async_t * handle);
+static void enter_alter_stmt(uv_async_t * handle);
+static void enter_alter_user(uv_async_t * handle);
+static void enter_count_stmt(uv_async_t * handle);
+static void enter_create_stmt(uv_async_t * handle);
+static void enter_create_user(uv_async_t * handle);
+static void enter_drop_stmt(uv_async_t * handle);
+static void enter_grant_user(uv_async_t * handle);
+static void enter_group_match(uv_async_t * handle);
+static void enter_help(uv_async_t * handle);
+static void enter_limit_expr(uv_async_t * handle);
+static void enter_list_stmt(uv_async_t * handle);
+static void enter_merge_as(uv_async_t * handle);
+static void enter_revoke_user(uv_async_t * handle);
+static void enter_select_stmt(uv_async_t * handle);
+static void enter_set_expression(uv_async_t * handle);
+static void enter_set_ignore_threshold(uv_async_t * handle);
+static void enter_set_name(uv_async_t * handle);
+static void enter_set_password(uv_async_t * handle);
+static void enter_series_all(uv_async_t * handle);
+static void enter_series_name(uv_async_t * handle);
+static void enter_series_match(uv_async_t * handle);
+static void enter_series_re(uv_async_t * handle);
+static void enter_series_sep(uv_async_t * handle);
+static void enter_timeit_stmt(uv_async_t * handle);
+static void enter_where_xxx(uv_async_t * handle);
+static void enter_xxx_columns(uv_async_t * handle);
+
+static void exit_after_expr(uv_async_t * handle);
+static void exit_alter_group(uv_async_t * handle);
+static void exit_alter_user(uv_async_t * handle);
+static void exit_before_expr(uv_async_t * handle);
+static void exit_between_expr(uv_async_t * handle);
+static void exit_calc_stmt(uv_async_t * handle);
+static void exit_count_groups(uv_async_t * handle);
+static void exit_count_pools(uv_async_t * handle);
+static void exit_count_series(uv_async_t * handle);
+static void exit_count_series_length(uv_async_t * handle);
+static void exit_count_servers(uv_async_t * handle);
+static void exit_count_servers_received(uv_async_t * handle);
+static void exit_count_servers_selected(uv_async_t * handle);
+static void exit_count_shards(uv_async_t * handle);
+static void exit_count_shards_size(uv_async_t * handle);
+static void exit_count_users(uv_async_t * handle);
+static void exit_create_group(uv_async_t * handle);
+static void exit_create_user(uv_async_t * handle);
+static void exit_drop_group(uv_async_t * handle);
+static void exit_drop_series(uv_async_t * handle);
+static void exit_drop_server(uv_async_t * handle);
+static void exit_drop_shards(uv_async_t * handle);
+static void exit_drop_user(uv_async_t * handle);
+static void exit_grant_user(uv_async_t * handle);
+static void exit_help_xxx(uv_async_t * handle);
+static void exit_list_groups(uv_async_t * handle);
+static void exit_list_pools(uv_async_t * handle);
+static void exit_list_series(uv_async_t * handle);
+static void exit_list_servers(uv_async_t * handle);
+static void exit_list_shards(uv_async_t * handle);
+static void exit_list_users(uv_async_t * handle);
+static void exit_revoke_user(uv_async_t * handle);
+static void exit_select_aggregate(uv_async_t * handle);
+static void exit_select_stmt(uv_async_t * handle);
+static void exit_series_match(uv_async_t * handle);
+static void exit_set_address(uv_async_t * handle);
+static void exit_set_backup_mode(uv_async_t * handle);
+static void exit_set_drop_threshold(uv_async_t * handle);
+static void exit_set_list_limit(uv_async_t * handle);
+static void exit_set_log_level(uv_async_t * handle);
+static void exit_set_port(uv_async_t * handle);
+static void exit_set_select_points_limit(uv_async_t * handle);
+static void exit_set_timezone(uv_async_t * handle);
+static void exit_show_stmt(uv_async_t * handle);
+static void exit_timeit_stmt(uv_async_t * handle);
+
+/* async loop functions */
+static void async_count_series(uv_async_t * handle);
+static void async_count_series_length(uv_async_t * handle);
+static void async_drop_series(uv_async_t * handle);
+static void async_drop_shards(uv_async_t * handle);
+static void async_filter_series(uv_async_t * handle);
+static void async_list_series(uv_async_t * handle);
+static void async_no_points_aggregate(uv_async_t * handle);
+static void async_select_aggregate(uv_async_t * handle);
+static void async_series_re(uv_async_t * handle);
+
+/* on response functions */
+static void on_ack_response(
+ sirinet_promise_t * promise,
+ sirinet_pkg_t * pkg,
+ int status);
+static void on_alter_xxx_response(slist_t * promises, uv_async_t * handle);
+static void on_count_xxx_response(slist_t * promises, uv_async_t * handle);
+static void on_drop_series_response(slist_t * promises, uv_async_t * handle);
+static void on_drop_shards_response(slist_t * promises, uv_async_t * handle);
+static void on_groups_response(slist_t * promises, uv_async_t * handle);
+static void on_list_xxx_response(slist_t * promises, uv_async_t * handle);
+static void on_select_response(slist_t * promises, uv_async_t * handle);
+static void on_update_xxx_response(slist_t * promises, uv_async_t * handle);
+
+/* helper functions */
+static void master_select_work(uv_work_t * handle);
+static void master_select_work_finish(uv_work_t * work, int status);
+static int items_select_master(
+ const char * name,
+ size_t len,
+ siridb_points_t * points,
+ uv_async_t * handle);
+static int items_select_master_merge(
+ const char * name,
+ size_t len,
+ slist_t * plist,
+ uv_async_t * handle);
+static int items_select_other(
+ const char * name,
+ size_t len,
+ siridb_points_t * points,
+ uv_async_t * handle);
+static int items_select_other_merge(
+ const char * name,
+ size_t len,
+ slist_t * plist,
+ uv_async_t * handle);
+static void on_select_unpack_points(
+ qp_unpacker_t * unpacker,
+ query_select_t * q_select,
+ qp_obj_t * qp_name,
+ qp_obj_t * qp_tp,
+ qp_obj_t * qp_len,
+ qp_obj_t * qp_points,
+ uint32_t select_points_limit);
+static void on_select_unpack_merged_points(
+ qp_unpacker_t * unpacker,
+ query_select_t * q_select,
+ qp_obj_t * qp_name,
+ qp_obj_t * qp_tp,
+ qp_obj_t * qp_len,
+ qp_obj_t * qp_points,
+ uint32_t select_points_limit);
+
+static int values_list_groups(siridb_group_t * group, uv_async_t * handle);
+static int values_count_groups(siridb_group_t * group, uv_async_t * handle);
+static void finish_list_groups(uv_async_t * handle);
+static void finish_count_groups(uv_async_t * handle);
+
+/* address bindings for default list properties */
+static uint32_t GID_K_NAME = CLERI_GID_K_NAME;
+static uint32_t GID_K_POOL = CLERI_GID_K_POOL;
+static uint32_t GID_K_VERSION = CLERI_GID_K_VERSION;
+static uint32_t GID_K_ONLINE = CLERI_GID_K_ONLINE;
+static uint32_t GID_K_STATUS = CLERI_GID_K_STATUS;
+static uint32_t GID_K_SERVER = CLERI_GID_K_SERVER;
+static uint32_t GID_K_SERVERS = CLERI_GID_K_SERVERS;
+static uint32_t GID_K_SERIES = CLERI_GID_K_SERIES;
+static uint32_t GID_K_SID = CLERI_GID_K_SID;
+static uint32_t GID_K_START = CLERI_GID_K_START;
+static uint32_t GID_K_END = CLERI_GID_K_END;
+
+/*
+ * Start SIRIPARSER_ASYNC_NEXT_NODE
+ */
+#define SIRIPARSER_ASYNC_NEXT_NODE \
+siridb_nodes_next(&query->nodes); \
+if (query->nodes == NULL) \
+{ \
+ siridb_send_query_result(handle); \
+} \
+else \
+{ \
+ uv_close((uv_handle_t *) handle, (uv_close_cb) free); \
+ handle = (uv_async_t *) malloc(sizeof(uv_async_t)); \
+ if (handle == NULL) \
+ { \
+ ERR_ALLOC \
+ } \
+ else \
+ { \
+ handle->data = query; \
+ uv_async_init(siri.loop, handle, (uv_async_cb) query->nodes->cb); \
+ uv_async_send(handle); \
+ } \
+}
+
+#define SIRIPARSER_NEXT_NODE \
+siridb_nodes_next(&query->nodes); \
+if (query->nodes == NULL) \
+{ \
+ siridb_send_query_result(handle); \
+} \
+else \
+{ \
+ handle->data = query; \
+ query->nodes->cb(handle); \
+}
+
+
+/*
+ * Start SIRIPARSER_MASTER_CHECK_ACCESS
+ */
+#define SIRIPARSER_MASTER_CHECK_ACCESS(user, ACCESS_BIT) \
+if (IS_MASTER && \
+ !siridb_user_check_access( \
+ user, \
+ ACCESS_BIT, \
+ query->err_msg)) \
+{ \
+ siridb_query_send_error(handle, CPROTO_ERR_USER_ACCESS); \
+ return; \
+}
+
+void siridb_init_listener(void)
+{
+ uint_fast16_t i;
+
+ for (i = 0; i < CLERI_END; i++)
+ {
+ siridb_listen_enter[i] = NULL;
+ siridb_listen_exit[i] = NULL;
+ }
+
+ siridb_listen_enter[CLERI_GID_ACCESS_EXPR] = enter_access_expr;
+ siridb_listen_enter[CLERI_GID_ALTER_GROUP] = enter_alter_group;
+ siridb_listen_enter[CLERI_GID_ALTER_SERVER] = enter_alter_server;
+ siridb_listen_enter[CLERI_GID_ALTER_SERVERS] = enter_alter_servers;
+ siridb_listen_enter[CLERI_GID_ALTER_STMT] = enter_alter_stmt;
+ siridb_listen_enter[CLERI_GID_ALTER_USER] = enter_alter_user;
+ siridb_listen_enter[CLERI_GID_COUNT_STMT] = enter_count_stmt;
+ siridb_listen_enter[CLERI_GID_CREATE_STMT] = enter_create_stmt;
+ siridb_listen_enter[CLERI_GID_CREATE_USER] = enter_create_user;
+ siridb_listen_enter[CLERI_GID_DROP_STMT] = enter_drop_stmt;
+ siridb_listen_enter[CLERI_GID_GRANT_USER] = enter_grant_user;
+ siridb_listen_enter[CLERI_GID_GROUP_COLUMNS] = enter_xxx_columns;
+ siridb_listen_enter[CLERI_GID_GROUP_MATCH] = enter_group_match;
+ siridb_listen_enter[CLERI_GID_HELP_STMT] = enter_help;
+ siridb_listen_enter[CLERI_GID_LIMIT_EXPR] = enter_limit_expr;
+ siridb_listen_enter[CLERI_GID_LIST_STMT] = enter_list_stmt;
+ siridb_listen_enter[CLERI_GID_MERGE_AS] = enter_merge_as;
+ siridb_listen_enter[CLERI_GID_POOL_COLUMNS] = enter_xxx_columns;
+ siridb_listen_enter[CLERI_GID_REVOKE_USER] = enter_revoke_user;
+ siridb_listen_enter[CLERI_GID_SELECT_STMT] = enter_select_stmt;
+ siridb_listen_enter[CLERI_GID_SET_EXPRESSION] = enter_set_expression;
+ siridb_listen_enter[CLERI_GID_SET_IGNORE_THRESHOLD] = enter_set_ignore_threshold;
+ siridb_listen_enter[CLERI_GID_SET_NAME] = enter_set_name;
+ siridb_listen_enter[CLERI_GID_SET_PASSWORD] = enter_set_password;
+ siridb_listen_enter[CLERI_GID_SERIES_COLUMNS] = enter_xxx_columns;
+ siridb_listen_enter[CLERI_GID_SERVER_COLUMNS] = enter_xxx_columns;
+ siridb_listen_enter[CLERI_GID_SERIES_ALL] = enter_series_all;
+ siridb_listen_enter[CLERI_GID_SERIES_NAME] = enter_series_name;
+ siridb_listen_enter[CLERI_GID_SERIES_MATCH] = enter_series_match;
+ siridb_listen_enter[CLERI_GID_SERIES_RE] = enter_series_re;
+ siridb_listen_enter[CLERI_GID_SERIES_SEP] = enter_series_sep;
+ siridb_listen_enter[CLERI_GID_SHARD_COLUMNS] = enter_xxx_columns;
+ siridb_listen_enter[CLERI_GID_TIMEIT_STMT] = enter_timeit_stmt;
+ siridb_listen_enter[CLERI_GID_USER_COLUMNS] = enter_xxx_columns;
+ siridb_listen_enter[CLERI_GID_WHERE_GROUP] = enter_where_xxx;
+ siridb_listen_enter[CLERI_GID_WHERE_POOL] = enter_where_xxx;
+ siridb_listen_enter[CLERI_GID_WHERE_SERIES] = enter_where_xxx;
+ siridb_listen_enter[CLERI_GID_WHERE_SERVER] = enter_where_xxx;
+ siridb_listen_enter[CLERI_GID_WHERE_SHARD] = enter_where_xxx;
+ siridb_listen_enter[CLERI_GID_WHERE_USER] = enter_where_xxx;
+
+
+ siridb_listen_exit[CLERI_GID_AFTER_EXPR] = exit_after_expr;
+ siridb_listen_exit[CLERI_GID_ALTER_GROUP] = exit_alter_group;
+ siridb_listen_exit[CLERI_GID_ALTER_USER] = exit_alter_user;
+ siridb_listen_exit[CLERI_GID_BEFORE_EXPR] = exit_before_expr;
+ siridb_listen_exit[CLERI_GID_BETWEEN_EXPR] = exit_between_expr;
+ siridb_listen_exit[CLERI_GID_CALC_STMT] = exit_calc_stmt;
+ siridb_listen_exit[CLERI_GID_COUNT_GROUPS] = exit_count_groups;
+ siridb_listen_exit[CLERI_GID_COUNT_POOLS] = exit_count_pools;
+ siridb_listen_exit[CLERI_GID_COUNT_SERIES] = exit_count_series;
+ siridb_listen_exit[CLERI_GID_COUNT_SERIES_LENGTH] = exit_count_series_length;
+ siridb_listen_exit[CLERI_GID_COUNT_SERVERS] = exit_count_servers;
+ siridb_listen_exit[CLERI_GID_COUNT_SERVERS_RECEIVED] = exit_count_servers_received;
+ siridb_listen_exit[CLERI_GID_COUNT_SERVERS_SELECTED] = exit_count_servers_selected;
+ siridb_listen_exit[CLERI_GID_COUNT_SHARDS] = exit_count_shards;
+ siridb_listen_exit[CLERI_GID_COUNT_SHARDS_SIZE] = exit_count_shards_size;
+ siridb_listen_exit[CLERI_GID_COUNT_USERS] = exit_count_users;
+ siridb_listen_exit[CLERI_GID_CREATE_GROUP] = exit_create_group;
+ siridb_listen_exit[CLERI_GID_CREATE_USER] = exit_create_user;
+ siridb_listen_exit[CLERI_GID_DROP_GROUP] = exit_drop_group;
+ siridb_listen_exit[CLERI_GID_DROP_SERIES] = exit_drop_series;
+ siridb_listen_exit[CLERI_GID_DROP_SERVER] = exit_drop_server;
+ siridb_listen_exit[CLERI_GID_DROP_SHARDS] = exit_drop_shards;
+ siridb_listen_exit[CLERI_GID_DROP_USER] = exit_drop_user;
+ siridb_listen_exit[CLERI_GID_GRANT_USER] = exit_grant_user;
+ siridb_listen_exit[CLERI_GID_LIST_GROUPS] = exit_list_groups;
+ siridb_listen_exit[CLERI_GID_LIST_POOLS] = exit_list_pools;
+ siridb_listen_exit[CLERI_GID_LIST_SERIES] = exit_list_series;
+ siridb_listen_exit[CLERI_GID_LIST_SERVERS] = exit_list_servers;
+ siridb_listen_exit[CLERI_GID_LIST_SHARDS] = exit_list_shards;
+ siridb_listen_exit[CLERI_GID_LIST_USERS] = exit_list_users;
+ siridb_listen_exit[CLERI_GID_REVOKE_USER] = exit_revoke_user;
+ siridb_listen_exit[CLERI_GID_SELECT_AGGREGATE] = exit_select_aggregate;
+ siridb_listen_exit[CLERI_GID_SELECT_STMT] = exit_select_stmt;
+ siridb_listen_exit[CLERI_GID_SERIES_MATCH] = exit_series_match;
+ siridb_listen_exit[CLERI_GID_SET_ADDRESS] = exit_set_address;
+ siridb_listen_exit[CLERI_GID_SET_BACKUP_MODE] = exit_set_backup_mode;
+ siridb_listen_exit[CLERI_GID_SET_DROP_THRESHOLD] = exit_set_drop_threshold;
+ siridb_listen_exit[CLERI_GID_SET_LIST_LIMIT] = exit_set_list_limit;
+ siridb_listen_exit[CLERI_GID_SET_LOG_LEVEL] = exit_set_log_level;
+ siridb_listen_exit[CLERI_GID_SET_PORT] = exit_set_port;
+ siridb_listen_exit[CLERI_GID_SET_SELECT_POINTS_LIMIT] = exit_set_select_points_limit;
+ siridb_listen_exit[CLERI_GID_SET_TIMEZONE] = exit_set_timezone;
+ siridb_listen_exit[CLERI_GID_SHOW_STMT] = exit_show_stmt;
+ siridb_listen_exit[CLERI_GID_TIMEIT_STMT] = exit_timeit_stmt;
+
+ for (i = HELP_OFFSET; i < HELP_OFFSET + HELP_COUNT; i++)
+ {
+ siridb_listen_exit[i] = exit_help_xxx;
+ }
+}
+
+/******************************************************************************
+ * Enter functions
+ *****************************************************************************/
+
+static void enter_access_expr(uv_async_t * handle)
+{
+ siridb_query_t * query = (siridb_query_t *) handle->data;
+
+ /* bind ACCESS_EXPR children to query */
+ query->data = query->nodes->node->children;
+
+ SIRIPARSER_NEXT_NODE
+}
+
+static void enter_alter_group(uv_async_t * handle)
+{
+ siridb_query_t * query = (siridb_query_t *) handle->data;
+ siridb_t * siridb = query->client->siridb;
+ query_alter_t * q_alter = (query_alter_t *) query->data;
+
+ MASTER_CHECK_ACCESSIBLE(siridb)
+
+ cleri_node_t * group_node =
+ query->nodes->node->children->next->node;
+ siridb_group_t * group;
+
+ char name[group_node->len - 1];
+ strx_extract_string(name, group_node->str, group_node->len);
+
+ if ((group = ct_get(siridb->groups->groups, name)) == NULL)
+ {
+ snprintf(query->err_msg,
+ SIRIDB_MAX_SIZE_ERR_MSG,
+ "Cannot find group: '%s'",
+ name);
+ siridb_query_send_error(handle, CPROTO_ERR_QUERY);
+ }
+ else
+ {
+ q_alter->alter_tp = QUERY_ALTER_GROUP;
+ q_alter->via.group = group;
+ siridb_group_incref(group);
+
+ SIRIPARSER_NEXT_NODE
+ }
+}
+
+static void enter_alter_server(uv_async_t * handle)
+{
+ siridb_query_t * query = (siridb_query_t *) handle->data;
+ siridb_t * siridb = query->client->siridb;
+ query_alter_t * q_alter = (query_alter_t *) query->data;
+ siridb_server_t * server = siridb_server_from_node(
+ siridb,
+ query->nodes->node->children->next->node->children->node,
+ query->err_msg);
+
+ if (server == NULL)
+ {
+ siridb_query_send_error(handle, CPROTO_ERR_QUERY);
+ }
+ else
+ {
+ q_alter->alter_tp = QUERY_ALTER_SERVER;
+ q_alter->via.server = server;
+ siridb_server_incref(server);
+
+ SIRIPARSER_NEXT_NODE
+ }
+}
+
+static void enter_alter_servers(uv_async_t * handle)
+{
+ siridb_query_t * query = (siridb_query_t *) handle->data;
+ ((query_alter_t *) query->data)->alter_tp = QUERY_ALTER_SERVERS;
+
+ SIRIPARSER_NEXT_NODE
+}
+
+static void enter_alter_stmt(uv_async_t * handle)
+{
+ siridb_query_t * query = (siridb_query_t *) handle->data;
+ siridb_user_t * db_user = query->client->origin;
+ SIRIPARSER_MASTER_CHECK_ACCESS(db_user, SIRIDB_ACCESS_ALTER)
+
+#if DEBUG
+ assert (query->packer == NULL);
+#endif
+
+ query->packer = sirinet_packer_new(1024);
+
+ if (query->packer == NULL)
+ {
+ MEM_ERR_RET
+ }
+
+ qp_add_type(query->packer, QP_MAP_OPEN);
+
+ query->data = query_alter_new();
+
+ if (query->data == NULL)
+ {
+ MEM_ERR_RET
+ }
+ query->free_cb = (uv_close_cb) query_alter_free;
+
+ SIRIPARSER_NEXT_NODE
+}
+
+static void enter_alter_user(uv_async_t * handle)
+{
+ siridb_query_t * query = (siridb_query_t *) handle->data;
+ siridb_t * siridb = query->client->siridb;
+
+ MASTER_CHECK_ACCESSIBLE(siridb)
+
+ cleri_node_t * user_node =
+ query->nodes->node->children->next->node;
+ query_alter_t * q_alter = (query_alter_t *) query->data;
+ siridb_user_t * user;
+
+ char name[user_node->len - 1];
+ strx_extract_string(name, user_node->str, user_node->len);
+
+ if ((user = siridb_users_get_user(siridb->users, name, NULL)) == NULL)
+ {
+ snprintf(query->err_msg,
+ SIRIDB_MAX_SIZE_ERR_MSG,
+ "Cannot find user: '%s'",
+ name);
+ siridb_query_send_error(handle, CPROTO_ERR_QUERY);
+ }
+ else
+ {
+ q_alter->alter_tp = QUERY_ALTER_USER;
+ q_alter->via.user = user;
+ siridb_user_incref(user);
+
+ SIRIPARSER_NEXT_NODE
+ }
+}
+
+static void enter_count_stmt(uv_async_t * handle)
+{
+ siridb_query_t * query = (siridb_query_t *) handle->data;
+ siridb_user_t * db_user = query->client->origin;
+ SIRIPARSER_MASTER_CHECK_ACCESS(db_user, SIRIDB_ACCESS_COUNT)
+
+#if DEBUG
+ assert (query->packer == NULL);
+#endif
+
+ query->packer = sirinet_packer_new(256);
+
+ if (query->packer == NULL)
+ {
+ MEM_ERR_RET
+ }
+
+ qp_add_type(query->packer, QP_MAP_OPEN);
+
+ query->data = query_count_new();
+
+ if (query->data == NULL)
+ {
+ MEM_ERR_RET
+ }
+
+ query->free_cb = (uv_close_cb) query_count_free;
+
+ SIRIPARSER_NEXT_NODE
+}
+
+static void enter_create_stmt(uv_async_t * handle)
+{
+ siridb_query_t * query = (siridb_query_t *) handle->data;
+ siridb_user_t * db_user = query->client->origin;
+ SIRIPARSER_MASTER_CHECK_ACCESS(db_user, SIRIDB_ACCESS_CREATE)
+
+ SIRIPARSER_NEXT_NODE
+}
+
+static void enter_create_user(uv_async_t * handle)
+{
+ siridb_query_t * query = (siridb_query_t *) handle->data;
+
+ /* bind user object to data and set correct free call */
+ query_alter_t * q_alter = query_alter_new();
+
+ query->data = q_alter;
+
+ if (q_alter == NULL)
+ {
+ MEM_ERR_RET
+ }
+
+ query->free_cb = (uv_close_cb) query_alter_free;
+ q_alter->via.user = siridb_user_new();
+
+ if (q_alter->via.user == NULL)
+ {
+ MEM_ERR_RET
+ }
+
+ q_alter->alter_tp = QUERY_ALTER_USER;
+
+ SIRIPARSER_NEXT_NODE
+}
+
+static void enter_drop_stmt(uv_async_t * handle)
+{
+ siridb_query_t * query = (siridb_query_t *) handle->data;
+ siridb_user_t * db_user = query->client->origin;
+
+#if DEBUG
+ assert (query->packer == NULL);
+#endif
+
+ SIRIPARSER_MASTER_CHECK_ACCESS(db_user, SIRIDB_ACCESS_DROP)
+
+ query->packer = sirinet_packer_new(1024);
+
+ if (query->packer == NULL)
+ {
+ MEM_ERR_RET
+ }
+
+ qp_add_type(query->packer, QP_MAP_OPEN);
+
+ query->data = query_drop_new();
+
+ if (query->data == NULL)
+ {
+ MEM_ERR_RET
+ }
+
+ query->free_cb = (uv_close_cb) query_drop_free;
+
+ SIRIPARSER_NEXT_NODE
+}
+
+static void enter_grant_user(uv_async_t * handle)
+{
+ siridb_query_t * query = (siridb_query_t *) handle->data;
+ siridb_t * siridb = query->client->siridb;
+ siridb_user_t * db_user = query->client->origin;
+ SIRIPARSER_MASTER_CHECK_ACCESS(db_user, SIRIDB_ACCESS_GRANT)
+ MASTER_CHECK_ACCESSIBLE(siridb)
+
+ cleri_node_t * user_node =
+ query->nodes->node->children->next->node;
+ siridb_user_t * user;
+ char username[user_node->len - 1];
+ strx_extract_string(username, user_node->str, user_node->len);
+
+ if ((user = siridb_users_get_user(siridb->users, username, NULL)) == NULL)
+ {
+ snprintf(query->err_msg, SIRIDB_MAX_SIZE_ERR_MSG,
+ "Cannot find user: '%s'", username);
+ siridb_query_send_error(handle, CPROTO_ERR_QUERY);
+ }
+ else
+ {
+ user->access_bit |=
+ siridb_access_from_children((cleri_children_t *) query->data);
+
+ query_alter_t * q_alter = query->data = query_alter_new();
+ if (q_alter == NULL)
+ {
+ MEM_ERR_RET
+ }
+
+ siridb_user_incref(user);
+
+ query->free_cb = (uv_close_cb) query_alter_free;
+ q_alter->alter_tp = QUERY_ALTER_USER;
+ q_alter->via.user = user;
+
+ SIRIPARSER_NEXT_NODE
+ }
+}
+static void enter_group_match(uv_async_t * handle)
+{
+ siridb_query_t * query = (siridb_query_t *) handle->data;
+ siridb_t * siridb = query->client->siridb;
+ cleri_node_t * node = query->nodes->node;
+ query_wrapper_t * q_wrapper = (query_wrapper_t *) query->data;
+
+ /* we must send this query to all pools */
+ if (q_wrapper->pmap != NULL)
+ {
+ imap_free(q_wrapper->pmap, NULL);
+ q_wrapper->pmap = NULL;
+ }
+
+ char group_name[node->len - 1];
+
+ /* extract series name */
+ strx_extract_string(group_name, node->str, node->len);
+
+ siridb_group_t * group =
+ (siridb_group_t *) ct_get(siridb->groups->groups, group_name);
+
+ if (group == NULL)
+ {
+ snprintf(query->err_msg,
+ SIRIDB_MAX_SIZE_ERR_MSG,
+ "Cannot find group '%s'",
+ group_name);
+ siridb_query_send_error(handle, CPROTO_ERR_QUERY);
+ }
+ else
+ {
+ siridb_series_t * series;
+ size_t i;
+
+ q_wrapper->series_tmp = (q_wrapper->update_cb == NULL) ?
+ q_wrapper->series_map : imap_new();
+
+ if (q_wrapper->series_tmp == NULL)
+ {
+ MEM_ERR_RET
+ }
+
+ uv_mutex_lock(&siridb->groups->mutex);
+
+ for (i = 0; i < group->series->len; i++)
+ {
+ series = (siridb_series_t *) group->series->data[i];
+ siridb_series_incref(series);
+ if (imap_add(q_wrapper->series_tmp, series->id, series))
+ {
+ log_critical("Cannot add series to temporary map.");
+ siridb_series_decref(series);
+ }
+ }
+
+ uv_mutex_unlock(&siridb->groups->mutex);
+
+ if (q_wrapper->update_cb != NULL)
+ {
+ (*q_wrapper->update_cb)(
+ q_wrapper->series_map,
+ q_wrapper->series_tmp,
+ (imap_free_cb) &siridb__series_decref);
+ }
+
+ q_wrapper->series_tmp = NULL;
+
+ SIRIPARSER_ASYNC_NEXT_NODE
+ }
+}
+
+static void enter_help(uv_async_t * handle)
+{
+ siridb_query_t * query = (siridb_query_t *) handle->data;
+
+ cleri_node_t * node = query->nodes->node;
+
+ query->data = strndup(node->str, node->len);
+
+ if (query->data == NULL)
+ {
+ MEM_ERR_RET
+ }
+
+ query->free_cb = (uv_close_cb) query_help_free;
+
+ strx_split_join(query->data, ' ', '_');
+
+ SIRIPARSER_ASYNC_NEXT_NODE
+}
+
+static void enter_limit_expr(uv_async_t * handle)
+{
+ siridb_query_t * query = (siridb_query_t *) handle->data;
+ siridb_t * siridb = query->client->siridb;
+ query_list_t * qlist = (query_list_t *) query->data;
+ int64_t limit = query->nodes->node->children->next->node->result;
+
+ if (limit <= 0 || limit > siridb->list_limit)
+ {
+ snprintf(query->err_msg, SIRIDB_MAX_SIZE_ERR_MSG,
+ "Limit must be a value between 0 and %" PRIu32
+ " but received: %" PRId64
+ " (optionally the limit can be changed, "
+ "see 'help alter database')",
+ siridb->list_limit,
+ limit);
+ siridb_query_send_error(handle, CPROTO_ERR_QUERY);
+ }
+ else
+ {
+ qlist->limit = limit;
+ SIRIPARSER_NEXT_NODE
+ }
+}
+
+static void enter_list_stmt(uv_async_t * handle)
+{
+ siridb_query_t * query = (siridb_query_t *) handle->data;
+ siridb_user_t * db_user = query->client->origin;
+ SIRIPARSER_MASTER_CHECK_ACCESS(db_user, SIRIDB_ACCESS_LIST)
+
+#if DEBUG
+ assert (query->packer == NULL);
+#endif
+
+ query->packer = sirinet_packer_new(QP_SUGGESTED_SIZE);
+
+ if (query->packer == NULL)
+ {
+ MEM_ERR_RET
+ }
+
+ qp_add_type(query->packer, QP_MAP_OPEN);
+
+ qp_add_raw(query->packer, (const unsigned char *) "columns", 7);
+ qp_add_type(query->packer, QP_ARRAY_OPEN);
+
+ query->data = query_list_new();
+
+ if (query->data == NULL)
+ {
+ MEM_ERR_RET
+ }
+
+ query->free_cb = (uv_close_cb) query_list_free;
+
+ SIRIPARSER_NEXT_NODE
+}
+
+static void enter_merge_as(uv_async_t * handle)
+{
+ siridb_query_t * query = (siridb_query_t *) handle->data;
+ query_select_t * q_select = (query_select_t *) query->data;
+ cleri_node_t * node = query->nodes->node->children->next->next->node;
+ q_select->merge_as = (char *) malloc(node->len - 1);
+
+ if (q_select->merge_as == NULL)
+ {
+ MEM_ERR_RET
+ }
+
+ strx_extract_string(q_select->merge_as, node->str, node->len);
+
+ if (IS_MASTER && query->nodes->node->children->next->next->next != NULL)
+ {
+ q_select->mlist = siridb_aggregate_list(
+ query->nodes->node->children->next->next->next->node->
+ children->node->children->next->node->children,
+ query->err_msg);
+
+ if (q_select->mlist == NULL)
+ {
+ siridb_query_send_error(handle, CPROTO_ERR_QUERY);
+ return;
+ }
+ }
+
+ SIRIPARSER_ASYNC_NEXT_NODE
+}
+
+static void enter_revoke_user(uv_async_t * handle)
+{
+ siridb_query_t * query = (siridb_query_t *) handle->data;
+ siridb_t * siridb = query->client->siridb;
+ siridb_user_t * db_user = query->client->origin;
+ SIRIPARSER_MASTER_CHECK_ACCESS(db_user, SIRIDB_ACCESS_REVOKE)
+ MASTER_CHECK_ACCESSIBLE(siridb)
+
+ cleri_node_t * user_node =
+ query->nodes->node->children->next->node;
+ siridb_user_t * user;
+ char username[user_node->len - 1];
+ strx_extract_string(username, user_node->str, user_node->len);
+
+ if ((user = siridb_users_get_user(siridb->users, username, NULL)) == NULL)
+ {
+ snprintf(query->err_msg,
+ SIRIDB_MAX_SIZE_ERR_MSG,
+ "Cannot find user: '%s'",
+ username);
+ siridb_query_send_error(handle, CPROTO_ERR_QUERY);
+ }
+ else
+ {
+ user->access_bit &=
+ ~siridb_access_from_children((cleri_children_t *) query->data);
+
+ query_alter_t * q_alter = query->data = query_alter_new();
+
+ if (q_alter == NULL)
+ {
+ MEM_ERR_RET
+ }
+
+ siridb_user_incref(user);
+
+ query->free_cb = (uv_close_cb) query_alter_free;
+ q_alter->alter_tp = QUERY_ALTER_USER;
+ q_alter->via.user = user;
+
+ SIRIPARSER_NEXT_NODE
+ }
+}
+
+static void enter_select_stmt(uv_async_t * handle)
+{
+ siridb_query_t * query = (siridb_query_t *) handle->data;
+ siridb_t * siridb = query->client->siridb;
+ query_select_t * q_select;
+ cleri_children_t * child;
+ int skip_get_points;
+ siridb_user_t * db_user = query->client->origin;
+ SIRIPARSER_MASTER_CHECK_ACCESS(db_user, SIRIDB_ACCESS_SELECT)
+ MASTER_CHECK_ACCESSIBLE(siridb)
+
+#if DEBUG
+ assert (query->packer == NULL && query->data == NULL);
+#endif
+
+ query->data = q_select = query_select_new();
+
+ if (q_select == NULL)
+ {
+ MEM_ERR_RET
+ }
+
+ /* this is not critical since pmap is allowed to be NULL */
+ ((query_select_t *) query->data)->pmap =
+ (!IS_MASTER || siridb_is_reindexing(siridb)) ?
+ NULL : imap_new();
+
+ /* child is always the ',' and child->next the node */
+ child = query->nodes->node->children->next->node->children;
+ skip_get_points = siridb_aggregate_can_skip(child);
+
+ child = child->next;
+ while (child != NULL)
+ {
+ if (skip_get_points && !siridb_aggregate_can_skip(child->next))
+ {
+ skip_get_points = 0;
+ }
+ q_select->nselects++;
+ child = child->next->next;
+ }
+
+ if (skip_get_points)
+ {
+ q_select->flags |= QUERIES_SKIP_GET_POINTS;
+ }
+
+ query->free_cb = (uv_close_cb) query_select_free;
+ query->packer = sirinet_packer_new(QP_SUGGESTED_SIZE);
+
+ if (query->packer == NULL)
+ {
+ MEM_ERR_RET
+ }
+
+ qp_add_type(query->packer, QP_MAP_OPEN);
+
+ SIRIPARSER_ASYNC_NEXT_NODE
+}
+
+static void enter_set_expression(uv_async_t * handle)
+{
+ siridb_query_t * query = (siridb_query_t *) handle->data;
+ siridb_t * siridb = query->client->siridb;
+ cleri_node_t * node = query->nodes->node->children->next->next->node;
+ query_alter_t * q_alter = (query_alter_t *) query->data;
+
+ if (siridb_group_update_expression(
+ siridb->groups,
+ q_alter->via.group,
+ node->str,
+ node->len,
+ query->err_msg))
+ {
+ siridb_query_send_error(handle, CPROTO_ERR_QUERY);
+ }
+ else
+ {
+ SIRIPARSER_ASYNC_NEXT_NODE
+ }
+}
+
+static void enter_set_ignore_threshold(uv_async_t * handle)
+{
+ siridb_query_t * query = (siridb_query_t *) handle->data;
+ query_drop_t * q_drop = (query_drop_t *) query->data;
+
+ if ( query->nodes->node->children->next->next->node->children->node->
+ cl_obj->gid == CLERI_GID_K_TRUE)
+ {
+ q_drop->flags |= QUERIES_IGNORE_DROP_THRESHOLD;
+ }
+
+ SIRIPARSER_NEXT_NODE
+}
+
+static void enter_set_name(uv_async_t * handle)
+{
+ siridb_query_t * query = (siridb_query_t *) handle->data;
+ siridb_t * siridb = query->client->siridb;
+ cleri_node_t * name_node =
+ query->nodes->node->children->next->next->node;
+
+ char name[name_node->len - 1];
+ strx_extract_string(name, name_node->str, name_node->len);
+
+ query_alter_t * q_alter = (query_alter_t *) query->data;
+ switch (q_alter->alter_tp)
+ {
+ case QUERY_ALTER_USER:
+ if (siridb_user_set_name(
+ siridb,
+ q_alter->via.user,
+ name,
+ query->err_msg))
+ {
+ siridb_query_send_error(handle, CPROTO_ERR_QUERY);
+ return;
+ }
+ break;
+ case QUERY_ALTER_GROUP:
+ if (siridb_group_set_name(
+ siridb->groups,
+ q_alter->via.group,
+ name,
+ query->err_msg))
+ {
+ siridb_query_send_error(handle, CPROTO_ERR_QUERY);
+ return;
+ }
+ break;
+ case QUERY_ALTER_NONE:
+ case QUERY_ALTER_DATABASE:
+ case QUERY_ALTER_SERVER:
+ default:
+ assert (0);
+ }
+
+ SIRIPARSER_NEXT_NODE
+}
+
+static void enter_set_password(uv_async_t * handle)
+{
+ siridb_query_t * query = (siridb_query_t *) handle->data;
+ siridb_user_t * user = ((query_alter_t *) query->data)->via.user;
+
+ cleri_node_t * pw_node =
+ query->nodes->node->children->next->next->node;
+
+ char password[pw_node->len - 1];
+ strx_extract_string(password, pw_node->str, pw_node->len);
+
+ if (siridb_user_set_password(user, password, query->err_msg))
+ {
+ siridb_query_send_error(handle, CPROTO_ERR_QUERY);
+ }
+ else
+ {
+ SIRIPARSER_NEXT_NODE
+ }
+}
+
+static void enter_series_name(uv_async_t * handle)
+{
+ siridb_query_t * query = (siridb_query_t *) handle->data;
+ cleri_node_t * node = query->nodes->node;
+ siridb_t * siridb = query->client->siridb;
+ query_wrapper_t * q_wrapper = (query_wrapper_t *) query->data;
+ siridb_series_t * series = NULL;
+ uint16_t pool;
+ char series_name[node->len - 1];
+
+ /* extract series name */
+ strx_extract_string(series_name, node->str, node->len);
+
+ if (siridb_is_reindexing(siridb))
+ {
+ series = (siridb_series_t *) ct_get(siridb->series, series_name);
+ }
+ else
+ {
+ /* get pool for series name */
+ pool = siridb_lookup_sn(siridb->pools->lookup, series_name);
+
+ /* check if this series belongs to 'this' pool and if so get the series */
+ if (pool == siridb->server->pool)
+ {
+ series = (siridb_series_t *) ct_get(siridb->series, series_name);
+ if (series == NULL)
+ {
+ /* the series does not exist */
+ snprintf(query->err_msg, SIRIDB_MAX_SIZE_ERR_MSG,
+ "Cannot find series: '%s'", series_name);
+
+ /* free series_name and return with send_errror.. */
+ siridb_query_send_error(handle, CPROTO_ERR_QUERY);
+ return;
+ }
+ }
+ else if (q_wrapper->pmap != NULL && imap_set(
+ q_wrapper->pmap,
+ pool,
+ (siridb_pool_t *) (siridb->pools->pool + pool)) < 0)
+ {
+ log_critical("Cannot add pool to pool map.");
+ }
+ }
+
+ if (series == NULL)
+ {
+ if (q_wrapper->update_cb == &imap_intersection_ref)
+ {
+ imap_free(
+ q_wrapper->series_map,
+ (imap_free_cb) &siridb__series_decref);
+
+ q_wrapper->series_map = imap_new();
+
+ if (q_wrapper->series_map == NULL)
+ {
+ MEM_ERR_RET
+ }
+ }
+ }
+ else
+ {
+ if ( q_wrapper->update_cb == NULL ||
+ q_wrapper->update_cb == &imap_union_ref)
+ {
+ if (imap_set(q_wrapper->series_map, series->id, series) == 1)
+ {
+ siridb_series_incref(series);
+ }
+ }
+ else if (q_wrapper->update_cb == &imap_difference_ref)
+ {
+ series = (siridb_series_t *) imap_pop(
+ q_wrapper->series_map,
+ series->id);
+ if (series != NULL)
+ {
+ siridb_series_decref(series);
+ }
+ }
+ else if (q_wrapper->update_cb == &imap_intersection_ref)
+ {
+ series = (siridb_series_t *) imap_get(
+ q_wrapper->series_map,
+ series->id);
+
+ if (series != NULL)
+ {
+ siridb_series_incref(series);
+ }
+
+ imap_free(
+ q_wrapper->series_map,
+ (imap_free_cb) &siridb__series_decref);
+
+ q_wrapper->series_map = imap_new();
+
+ if (q_wrapper->series_map == NULL)
+ {
+ if (series != NULL)
+ {
+ siridb_series_decref(series);
+ }
+ MEM_ERR_RET
+ }
+
+ if (series != NULL)
+ {
+ if (imap_set(q_wrapper->series_map, series->id, series) != 1)
+ {
+ siridb_series_decref(series);
+ MEM_ERR_RET
+ }
+ }
+ }
+ else if (q_wrapper->update_cb == &imap_symmetric_difference_ref)
+ {
+ switch (imap_set(q_wrapper->series_map, series->id, series))
+ {
+ case 0:
+ series = (siridb_series_t *) imap_pop(
+ q_wrapper->series_map,
+ series->id);
+ siridb_series_decref(series);
+ break;
+
+ case 1:
+ siridb_series_incref(series);
+ break;
+
+ default:
+ MEM_ERR_RET
+ }
+ }
+ else
+ {
+ /* we should not get here */
+ assert (0);
+ }
+ }
+
+ SIRIPARSER_ASYNC_NEXT_NODE
+}
+
+static void enter_series_match(uv_async_t * handle)
+{
+ siridb_query_t * query = (siridb_query_t *) handle->data;
+
+ if ((((query_wrapper_t *) query->data)->series_map = imap_new()) == NULL)
+ {
+ MEM_ERR_RET
+ }
+
+ SIRIPARSER_NEXT_NODE
+}
+
+static void enter_series_all(uv_async_t * handle)
+{
+ siridb_query_t * query = (siridb_query_t *) handle->data;
+ siridb_t * siridb = query->client->siridb;
+ siridb_series_t * series;
+ query_wrapper_t * q_wrapper = (query_wrapper_t *) query->data;
+
+ /* we must send this query to all pools */
+ if (q_wrapper->pmap != NULL)
+ {
+ imap_free(q_wrapper->pmap, NULL);
+ q_wrapper->pmap = NULL;
+ }
+
+ uv_mutex_lock(&siridb->series_mutex);
+
+ q_wrapper->slist = imap_2slist_ref(
+ ( q_wrapper->update_cb == NULL ||
+ q_wrapper->update_cb == &imap_union_ref ||
+ q_wrapper->update_cb == &imap_symmetric_difference_ref) ?
+ siridb->series_map : q_wrapper->series_map);
+
+ uv_mutex_unlock(&siridb->series_mutex);
+
+ q_wrapper->series_tmp = (q_wrapper->update_cb == NULL) ?
+ q_wrapper->series_map : imap_new();
+
+ if (q_wrapper->slist == NULL || q_wrapper->series_tmp == NULL)
+ {
+ MEM_ERR_RET
+ }
+
+ for (q_wrapper->slist_index = 0;
+ q_wrapper->slist_index < q_wrapper->slist->len;
+ ++q_wrapper->slist_index)
+ {
+ series = q_wrapper->slist->data[q_wrapper->slist_index];
+ if (imap_add(q_wrapper->series_tmp, series->id, series))
+ {
+ MEM_ERR_RET
+ }
+ }
+
+ slist_free(q_wrapper->slist);
+ q_wrapper->slist = NULL;
+ q_wrapper->slist_index = 0;
+
+ if (q_wrapper->update_cb != NULL)
+ {
+ (*q_wrapper->update_cb)(
+ q_wrapper->series_map,
+ q_wrapper->series_tmp,
+ (imap_free_cb) &siridb__series_decref);
+ }
+
+ q_wrapper->series_tmp = NULL;
+ SIRIPARSER_ASYNC_NEXT_NODE
+}
+
+static void enter_series_re(uv_async_t * handle)
+{
+ siridb_query_t * query = (siridb_query_t *) handle->data;
+ siridb_t * siridb = query->client->siridb;
+ cleri_node_t * node = query->nodes->node;
+ query_wrapper_t * q_wrapper = (query_wrapper_t *) query->data;
+
+ /* we must send this query to all pools */
+ if (q_wrapper->pmap != NULL)
+ {
+ imap_free(q_wrapper->pmap, NULL);
+ q_wrapper->pmap = NULL;
+ }
+
+ /* extract and compile regular expression */
+ if (siridb_re_compile(
+ &q_wrapper->regex,
+ &q_wrapper->match_data,
+ node->str,
+ node->len,
+ query->err_msg))
+ {
+ siridb_query_send_error(handle, CPROTO_ERR_QUERY);
+ }
+ else
+ {
+ uv_mutex_lock(&siridb->series_mutex);
+
+ q_wrapper->slist = imap_2slist_ref(
+ ( q_wrapper->update_cb == NULL ||
+ q_wrapper->update_cb == &imap_union_ref ||
+ q_wrapper->update_cb == &imap_symmetric_difference_ref) ?
+ siridb->series_map : q_wrapper->series_map);
+
+ uv_mutex_unlock(&siridb->series_mutex);
+
+ q_wrapper->series_tmp = (q_wrapper->update_cb == NULL) ?
+ q_wrapper->series_map : imap_new();
+
+ if (q_wrapper->slist == NULL || q_wrapper->series_tmp == NULL)
+ {
+ MEM_ERR_RET
+ }
+
+ uv_async_t * next =
+ (uv_async_t *) malloc(sizeof(uv_async_t));
+
+ if (next == NULL)
+ {
+ MEM_ERR_RET
+ }
+
+ next->data = handle->data;
+
+ uv_async_init(
+ siri.loop,
+ next,
+ (uv_async_cb) async_series_re);
+ uv_async_send(next);
+
+ uv_close((uv_handle_t *) handle, (uv_close_cb) free);
+ }
+
+ /* handle is handled or a signal is raised */
+}
+
+static void enter_series_sep(uv_async_t * handle)
+{
+ siridb_query_t * query = (siridb_query_t *) handle->data;
+ query_wrapper_t * q_wrapper = (query_wrapper_t *) query->data;
+
+ switch (query->nodes->node->children->node->cl_obj->gid)
+ {
+ case CLERI_GID_K_UNION:
+ q_wrapper->update_cb = &imap_union_ref;
+ break;
+ case CLERI_GID_K_INTERSECTION:
+ q_wrapper->update_cb = &imap_intersection_ref;
+ break;
+ case CLERI_GID_C_DIFFERENCE:
+ q_wrapper->update_cb = &imap_difference_ref;
+ break;
+ case CLERI_GID_K_SYMMETRIC_DIFFERENCE:
+ q_wrapper->update_cb = &imap_symmetric_difference_ref;
+ break;
+ default:
+ assert (0);
+ break;
+ }
+
+ SIRIPARSER_NEXT_NODE
+}
+
+static void enter_timeit_stmt(uv_async_t * handle)
+{
+ siridb_query_t * query = (siridb_query_t *) handle->data;
+ query->timeit = qp_packer_new(512);
+
+ if (query->timeit == NULL)
+ {
+ MEM_ERR_RET
+ }
+
+ qp_add_raw(query->timeit, (const unsigned char *) "__timeit__", 10);
+ qp_add_type(query->timeit, QP_ARRAY_OPEN);
+
+ SIRIPARSER_NEXT_NODE
+}
+
+static void enter_where_xxx(uv_async_t * handle)
+{
+ siridb_query_t * query = (siridb_query_t *) handle->data;
+ cexpr_t * cexpr =
+ cexpr_from_node(query->nodes->node->children->next->node);
+
+ if (cexpr == NULL)
+ {
+ sprintf(query->err_msg, "Max depth reached in 'where' expression!");
+ siridb_query_send_error(handle, CPROTO_ERR_QUERY);
+ }
+ else
+ {
+ ((query_wrapper_t *) query->data)->where_expr = cexpr;
+ SIRIPARSER_ASYNC_NEXT_NODE
+ }
+}
+
+static void enter_xxx_columns(uv_async_t * handle)
+{
+ siridb_query_t * query = (siridb_query_t *) handle->data;
+ cleri_children_t * columns = query->nodes->node->children;
+ query_list_t * qlist = (query_list_t *) query->data;
+
+ qlist->props = slist_new(DEFAULT_ALLOC_COLUMNS);
+
+ if (qlist->props == NULL)
+ {
+ MEM_ERR_RET
+ }
+
+ while (1)
+ {
+ qp_add_raw(
+ query->packer,
+ (const unsigned char *) columns->node->str,
+ columns->node->len);
+
+ if (slist_append_safe(
+ &qlist->props,
+ &columns->node->children->node->cl_obj->gid))
+ {
+ MEM_ERR_RET
+ }
+
+ if (columns->next == NULL)
+ {
+ break;
+ }
+
+ columns = columns->next->next;
+ }
+
+ SIRIPARSER_ASYNC_NEXT_NODE
+}
+
+/******************************************************************************
+ * Exit functions
+ *****************************************************************************/
+
+static void exit_after_expr(uv_async_t * handle)
+{
+ siridb_query_t * query = (siridb_query_t *) handle->data;
+ ((query_select_t *) query->data)->start_ts =
+ (uint64_t *) &query->nodes->node->children->next->node->result;
+
+ SIRIPARSER_NEXT_NODE
+}
+
+static void exit_alter_group(uv_async_t * handle)
+{
+ siridb_query_t * query = (siridb_query_t *) handle->data;
+ siridb_t * siridb = query->client->siridb;
+
+ if (siridb_groups_save(siridb->groups))
+ {
+ FILE_ERR_RET
+ }
+
+ QP_ADD_SUCCESS
+ char * name = ((query_alter_t *) query->data)->via.group->name;
+ log_info(MSG_SUCCESS_ALTER_GROUP, name);
+ qp_add_fmt_safe(query->packer, MSG_SUCCESS_ALTER_GROUP, name);
+
+ if (IS_MASTER)
+ {
+ siridb_query_forward(
+ handle,
+ SIRIDB_QUERY_FWD_UPDATE,
+ (sirinet_promises_cb) on_update_xxx_response,
+ 0);
+ }
+ else
+ {
+ SIRIPARSER_ASYNC_NEXT_NODE
+ }
+}
+
+static void exit_alter_user(uv_async_t * handle)
+{
+ siridb_query_t * query = (siridb_query_t *) handle->data;
+ siridb_t * siridb = query->client->siridb;
+
+ if (siridb_users_save(siridb))
+ {
+ FILE_ERR_RET
+ }
+
+ QP_ADD_SUCCESS
+ char * name = ((query_alter_t *) query->data)->via.user->name;
+ log_info(MSG_SUCCESS_ALTER_USER, name);
+ qp_add_fmt_safe(query->packer, MSG_SUCCESS_ALTER_USER, name);
+
+ if (IS_MASTER)
+ {
+ siridb_query_forward(
+ handle,
+ SIRIDB_QUERY_FWD_UPDATE,
+ (sirinet_promises_cb) on_update_xxx_response,
+ 0);
+ }
+ else
+ {
+ SIRIPARSER_ASYNC_NEXT_NODE
+ }
+}
+
+static void exit_before_expr(uv_async_t * handle)
+{
+ siridb_query_t * query = (siridb_query_t *) handle->data;
+
+ ((query_select_t *) query->data)->end_ts =
+ (uint64_t *) &query->nodes->node->children->next->node->result;
+
+ SIRIPARSER_NEXT_NODE
+}
+
+static void exit_between_expr(uv_async_t * handle)
+{
+ siridb_query_t * query = (siridb_query_t *) handle->data;
+ query_select_t * q_select = (query_select_t *) query->data;
+
+ q_select->start_ts = (uint64_t *)
+ &query->nodes->node->children->next->node->result;
+
+ q_select->end_ts = (uint64_t *)
+ &query->nodes->node->children->next->next->next->node->result;
+
+ if (*q_select->start_ts > *q_select->end_ts)
+ {
+ snprintf(query->err_msg,
+ SIRIDB_MAX_SIZE_ERR_MSG,
+ "Start time (%" PRIu64 ") "
+ "should not be greater than end time (%" PRIu64 ")",
+ *q_select->start_ts,
+ *q_select->end_ts);
+ siridb_query_send_error(handle, CPROTO_ERR_QUERY);
+ }
+ else
+ {
+ SIRIPARSER_NEXT_NODE
+ }
+}
+
+static void exit_calc_stmt(uv_async_t * handle)
+{
+ siridb_query_t * query = (siridb_query_t *) handle->data;
+ cleri_node_t * calc_node = query->nodes->node;
+
+#if DEBUG
+ assert (query->packer == NULL);
+#endif
+
+ query->packer = sirinet_packer_new(64);
+
+ if (query->packer == NULL)
+ {
+ MEM_ERR_RET
+ }
+
+ qp_add_type(query->packer, QP_MAP_OPEN);
+ qp_add_raw(query->packer, (const unsigned char *) "calc", 4);
+
+ if (!query->factor)
+ {
+ qp_add_int64(query->packer, calc_node->result);
+ }
+ else
+ {
+ double factor = (double) query->factor;
+ qp_add_int64(query->packer, (int64_t) (calc_node->result * factor));
+ }
+
+ SIRIPARSER_ASYNC_NEXT_NODE
+}
+
+static void exit_count_groups(uv_async_t * handle)
+{
+ siridb_query_t * query = (siridb_query_t *) handle->data;
+ siridb_t * siridb = query->client->siridb;
+ query_count_t * q_count = (query_count_t *) query->data;
+
+ if (q_count->where_expr == NULL || !cexpr_contains(
+ q_count->where_expr,
+ siridb_group_is_remote_prop))
+ {
+ finish_count_groups(handle);
+ }
+ else
+ {
+ sirinet_pkg_t * pkg = sirinet_pkg_new(0, 0, BPROTO_REQ_GROUPS, NULL);
+
+ if (pkg != NULL)
+ {
+ siri_async_incref(handle);
+
+ query->nodes->cb = (uv_async_cb) finish_count_groups;
+
+ siridb_pools_send_pkg(
+ siridb,
+ pkg,
+ 0,
+ (sirinet_promises_cb) on_groups_response,
+ handle,
+ 0);
+ }
+ }
+}
+
+static void exit_count_pools(uv_async_t * handle)
+{
+ siridb_query_t * query = (siridb_query_t *) handle->data;
+ siridb_t * siridb = query->client->siridb;
+ query_count_t * q_count = (query_count_t *) query->data;
+ siridb_pool_t * pool = siridb->pools->pool + siridb->server->pool;
+
+ siridb_pool_walker_t wpool = {
+ .servers=pool->len,
+ .series=siridb->series->len,
+ .pool=siridb->server->pool
+ };
+
+ qp_add_raw(query->packer, (const unsigned char *) "pools", 5);
+
+ if (q_count->where_expr == NULL)
+ {
+ qp_add_int64(query->packer, siridb->pools->len);
+ SIRIPARSER_ASYNC_NEXT_NODE
+ }
+ else
+ {
+ MASTER_CHECK_ACCESSIBLE(siridb)
+
+ q_count->n = cexpr_run(
+ q_count->where_expr,
+ (cexpr_cb_t) siridb_pool_cexpr_cb,
+ &wpool);
+
+ if (IS_MASTER)
+ {
+ siridb_query_forward(
+ handle,
+ SIRIDB_QUERY_FWD_POOLS,
+ (sirinet_promises_cb) on_count_xxx_response,
+ 0);
+ }
+ else
+ {
+ qp_add_int64(query->packer, q_count->n);
+ SIRIPARSER_ASYNC_NEXT_NODE
+ }
+ }
+}
+
+static void exit_count_series(uv_async_t * handle)
+{
+ siridb_query_t * query = (siridb_query_t *) handle->data;
+ siridb_t * siridb = query->client->siridb;
+ query_count_t * q_count = (query_count_t *) query->data;
+
+ MASTER_CHECK_ONLINE(siridb)
+
+ qp_add_raw(query->packer, (const unsigned char *) "series", 6);
+
+ if (q_count->where_expr == NULL)
+ {
+ q_count->n = (q_count->series_map == NULL) ?
+ siridb->series_map->len : q_count->series_map->len;
+
+ if (IS_MASTER)
+ {
+ siridb_query_forward(
+ handle,
+ SIRIDB_QUERY_FWD_POOLS,
+ (sirinet_promises_cb) on_count_xxx_response,
+ 0);
+ }
+ else
+ {
+ qp_add_int64(query->packer, q_count->n);
+
+ SIRIPARSER_ASYNC_NEXT_NODE
+ }
+ }
+ else
+ {
+ uv_mutex_lock(&siridb->series_mutex);
+
+ q_count->slist = imap_2slist_ref(
+ (q_count->series_map == NULL) ?
+ siridb->series_map : q_count->series_map);
+
+ uv_mutex_unlock(&siridb->series_mutex);
+
+ if (q_count->slist == NULL)
+ {
+ MEM_ERR_RET
+ }
+
+ uv_async_t * next =
+ (uv_async_t *) malloc(sizeof(uv_async_t));
+ if (next == NULL)
+ {
+ MEM_ERR_RET
+ }
+
+ next->data = handle->data;
+
+ uv_async_init(
+ siri.loop,
+ next,
+ (uv_async_cb) async_count_series);
+ uv_async_send(next);
+
+ uv_close((uv_handle_t *) handle, (uv_close_cb) free);
+ }
+}
+
+static void exit_count_series_length(uv_async_t * handle)
+{
+ siridb_query_t * query = (siridb_query_t *) handle->data;
+ siridb_t * siridb = query->client->siridb;
+ query_count_t * q_count = (query_count_t *) query->data;
+
+ MASTER_CHECK_ACCESSIBLE(siridb)
+
+ qp_add_raw(query->packer, (const unsigned char *) "series_length", 13);
+
+ if (q_count->where_expr == NULL)
+ {
+ size_t i;
+ slist_t * slist;
+ siridb_series_t * series;
+
+ uv_mutex_lock(&siridb->series_mutex);
+
+ slist = imap_2slist((q_count->series_map == NULL) ?
+ siridb->series_map : q_count->series_map);
+
+ uv_mutex_unlock(&siridb->series_mutex);
+
+ if (slist == NULL)
+ {
+ MEM_ERR_RET
+ }
+
+ for (i = 0; i < slist->len; i++)
+ {
+ series = (siridb_series_t *) slist->data[i];
+ q_count->n += series->length;
+ }
+
+ slist_free(slist);
+
+ if (IS_MASTER)
+ {
+ siridb_query_forward(
+ handle,
+ SIRIDB_QUERY_FWD_POOLS,
+ (sirinet_promises_cb) on_count_xxx_response,
+ 0);
+ }
+ else
+ {
+ qp_add_int64(query->packer, q_count->n);
+
+ SIRIPARSER_ASYNC_NEXT_NODE
+ }
+ }
+ else
+ {
+ uv_async_t * next;
+
+ uv_mutex_lock(&siridb->series_mutex);
+
+ q_count->slist = imap_2slist_ref(
+ (q_count->series_map == NULL) ?
+ siridb->series_map : q_count->series_map);
+
+ uv_mutex_unlock(&siridb->series_mutex);
+
+ if (q_count->slist == NULL)
+ {
+ MEM_ERR_RET
+ }
+
+ next = (uv_async_t *) malloc(sizeof(uv_async_t));
+
+ if (next == NULL)
+ {
+ MEM_ERR_RET
+ }
+
+ next->data = handle->data;
+
+ uv_async_init(
+ siri.loop,
+ next,
+ (uv_async_cb) async_count_series_length);
+ uv_async_send(next);
+
+ uv_close((uv_handle_t *) handle, (uv_close_cb) free);
+ }
+}
+
+static void exit_count_servers(uv_async_t * handle)
+{
+ siridb_query_t * query = (siridb_query_t *) handle->data;
+ siridb_t * siridb = query->client->siridb;
+ query_count_t * q_count = (query_count_t *) query->data;
+ cexpr_t * where_expr = q_count->where_expr;
+ cexpr_cb_t cb = (cexpr_cb_t) siridb_server_cexpr_cb;
+ int is_local = IS_MASTER;
+
+ qp_add_raw(query->packer, (const unsigned char *) "servers", 7);
+
+
+ /* if is_local, check if we use 'remote' props in where expression */
+ if (is_local && where_expr != NULL)
+ {
+ is_local = !cexpr_contains(where_expr, siridb_server_is_remote_prop);
+ }
+
+ if (is_local)
+ {
+ llist_node_t * node;
+ for ( node = siridb->servers->first;
+ node != NULL;
+ node = node->next)
+ {
+ siridb_server_walker_t wserver = {node->data, siridb};
+ if (where_expr == NULL || cexpr_run(where_expr, cb, &wserver))
+ {
+ q_count->n++;
+ }
+ }
+ }
+ else
+ {
+ siridb_server_walker_t wserver = {siridb->server, siridb};
+ if (where_expr == NULL || cexpr_run(where_expr, cb, &wserver))
+ {
+ q_count->n++;
+ }
+ }
+
+ if (IS_MASTER && !is_local)
+ {
+ siridb_query_forward(
+ handle,
+ SIRIDB_QUERY_FWD_SERVERS,
+ (sirinet_promises_cb) on_count_xxx_response,
+ 0);
+ }
+ else
+ {
+ qp_add_int64(query->packer, q_count->n);
+ SIRIPARSER_ASYNC_NEXT_NODE
+ }
+}
+
+static void exit_count_servers_received(uv_async_t * handle)
+{
+ siridb_query_t * query = (siridb_query_t *) handle->data;
+ siridb_t * siridb = query->client->siridb;
+ query_count_t * q_count = (query_count_t *) query->data;
+ cexpr_t * where_expr = q_count->where_expr;
+ cexpr_cb_t cb = (cexpr_cb_t) siridb_server_cexpr_cb;
+
+ qp_add_raw(
+ query->packer,
+ (const unsigned char *) "servers_received_points",
+ 23);
+
+ siridb_server_walker_t wserver = {siridb->server, siridb};
+ if (where_expr == NULL || cexpr_run(where_expr, cb, &wserver))
+ {
+ q_count->n += siridb->received_points;
+ }
+
+ if (IS_MASTER)
+ {
+ siridb_query_forward(
+ handle,
+ SIRIDB_QUERY_FWD_SERVERS,
+ (sirinet_promises_cb) on_count_xxx_response,
+ 0);
+ }
+ else
+ {
+ qp_add_int64(query->packer, q_count->n);
+ SIRIPARSER_ASYNC_NEXT_NODE
+ }
+}
+
+static void exit_count_servers_selected(uv_async_t * handle)
+{
+ siridb_query_t * query = (siridb_query_t *) handle->data;
+ siridb_t * siridb = query->client->siridb;
+ query_count_t * q_count = (query_count_t *) query->data;
+ cexpr_t * where_expr = q_count->where_expr;
+ cexpr_cb_t cb = (cexpr_cb_t) siridb_server_cexpr_cb;
+
+ qp_add_raw(
+ query->packer,
+ (const unsigned char *) "servers_selected_points",
+ 23);
+
+ siridb_server_walker_t wserver = {siridb->server, siridb};
+ if (where_expr == NULL || cexpr_run(where_expr, cb, &wserver))
+ {
+ q_count->n += siridb->selected_points;
+ }
+
+ if (IS_MASTER)
+ {
+ siridb_query_forward(
+ handle,
+ SIRIDB_QUERY_FWD_SERVERS,
+ (sirinet_promises_cb) on_count_xxx_response,
+ 0);
+ }
+ else
+ {
+ qp_add_int64(query->packer, q_count->n);
+ SIRIPARSER_ASYNC_NEXT_NODE
+ }
+}
+
+static void exit_count_shards(uv_async_t * handle)
+{
+ siridb_query_t * query = (siridb_query_t *) handle->data;
+ siridb_t * siridb = query->client->siridb;
+ query_count_t * q_count = (query_count_t *) query->data;
+
+ qp_add_raw(query->packer, (const unsigned char *) "shards", 6);
+
+ if (q_count->where_expr == NULL)
+ {
+ q_count->n = siridb->shards->len;
+ }
+ else
+ {
+ uint64_t duration;
+ siridb_shard_view_t vshard = {
+ .server=siridb->server
+ };
+ size_t i;
+ slist_t * shards_list;
+
+ uv_mutex_lock(&siridb->shards_mutex);
+
+ shards_list = imap_2slist_ref(siridb->shards);
+
+ uv_mutex_unlock(&siridb->shards_mutex);
+
+ if (shards_list == NULL)
+ {
+ MEM_ERR_RET
+ }
+
+ for (i = 0; i < shards_list->len; i++)
+ {
+ vshard.shard = (siridb_shard_t *) shards_list->data[i];
+
+ /* set start and end properties */
+ duration = (vshard.shard->tp == SIRIDB_SHARD_TP_NUMBER) ?
+ siridb->duration_num : siridb->duration_log;
+ vshard.start = vshard.shard->id - vshard.shard->id % duration;
+ vshard.end = vshard.start + duration;
+
+ if (cexpr_run(
+ q_count->where_expr,
+ (cexpr_cb_t) siridb_shard_cexpr_cb,
+ &vshard))
+ {
+ q_count->n++;
+ }
+
+ siridb_shard_decref(vshard.shard);
+ }
+
+ slist_free(shards_list);
+ }
+
+ if (IS_MASTER)
+ {
+ siridb_query_forward(
+ handle,
+ SIRIDB_QUERY_FWD_SERVERS,
+ (sirinet_promises_cb) on_count_xxx_response,
+ 0);
+ }
+ else
+ {
+ qp_add_int64(query->packer, q_count->n);
+ SIRIPARSER_ASYNC_NEXT_NODE
+ }
+}
+
+static void exit_count_shards_size(uv_async_t * handle)
+{
+ siridb_query_t * query = (siridb_query_t *) handle->data;
+ siridb_t * siridb = query->client->siridb;
+ query_count_t * q_count = (query_count_t *) query->data;
+ uint64_t duration;
+ size_t i;
+ slist_t * shards_list;
+ siridb_shard_view_t vshard = {
+ .server=siridb->server
+ };
+
+ qp_add_raw(query->packer, (const unsigned char *) "shards_size", 11);
+
+ uv_mutex_lock(&siridb->shards_mutex);
+
+ shards_list = imap_2slist_ref(siridb->shards);
+
+ uv_mutex_unlock(&siridb->shards_mutex);
+
+ if (shards_list == NULL)
+ {
+ MEM_ERR_RET
+ }
+
+ for (i = 0; i < shards_list->len; i++)
+ {
+ vshard.shard = (siridb_shard_t *) shards_list->data[i];
+
+ /* set start and end properties */
+ duration = (vshard.shard->tp == SIRIDB_SHARD_TP_NUMBER) ?
+ siridb->duration_num : siridb->duration_log;
+ vshard.start = vshard.shard->id - vshard.shard->id % duration;
+ vshard.end = vshard.start + duration;
+
+ if (q_count->where_expr == NULL || cexpr_run(
+ q_count->where_expr,
+ (cexpr_cb_t) siridb_shard_cexpr_cb,
+ &vshard))
+ {
+ q_count->n += vshard.shard->len;
+ }
+
+ siridb_shard_decref(vshard.shard);
+ }
+
+ slist_free(shards_list);
+
+ if (IS_MASTER)
+ {
+ siridb_query_forward(
+ handle,
+ SIRIDB_QUERY_FWD_SERVERS,
+ (sirinet_promises_cb) on_count_xxx_response,
+ 0);
+ }
+ else
+ {
+ qp_add_int64(query->packer, q_count->n);
+ SIRIPARSER_ASYNC_NEXT_NODE
+ }
+}
+
+static void exit_count_users(uv_async_t * handle)
+{
+ siridb_query_t * query = (siridb_query_t *) handle->data;
+ siridb_t * siridb = query->client->siridb;
+ llist_node_t * node = siridb->users->first;
+ cexpr_t * where_expr = ((query_count_t *) query->data)->where_expr;
+ cexpr_cb_t cb = (cexpr_cb_t) siridb_user_cexpr_cb;
+ int n = 0;
+
+ qp_add_raw(query->packer, (const unsigned char *) "users", 5);
+
+ while (node != NULL)
+ {
+ if (where_expr == NULL || cexpr_run(where_expr, cb, node->data))
+ {
+ n++;
+ }
+ node = node->next;
+ }
+
+ qp_add_int64(query->packer, n);
+
+ SIRIPARSER_ASYNC_NEXT_NODE
+}
+
+static void exit_create_group(uv_async_t * handle)
+{
+ siridb_query_t * query = (siridb_query_t *) handle->data;
+ siridb_t * siridb = query->client->siridb;
+ cleri_node_t * name_nd =
+ query->nodes->node->children->next->node;
+
+ cleri_node_t * for_nd =
+ query->nodes->node->children->next->next->next->node;
+
+ MASTER_CHECK_ACCESSIBLE(siridb)
+
+ char group_name[name_nd->len - 1];
+ strx_extract_string(group_name, name_nd->str, name_nd->len);
+
+ if (siridb_groups_add_group(
+ siridb->groups,
+ group_name,
+ for_nd->str,
+ for_nd->len,
+ query->err_msg))
+ {
+ siridb_query_send_error(handle, CPROTO_ERR_QUERY);
+ }
+ else if (siridb_groups_save(siridb->groups))
+ {
+ snprintf(query->err_msg,
+ SIRIDB_MAX_SIZE_ERR_MSG,
+ "Cannot write groups to file: %s",
+ siridb->groups->fn);
+ siridb_query_send_error(handle, CPROTO_ERR_QUERY);
+ log_critical("%s", query->err_msg);
+ }
+ else
+ {
+#if DEBUG
+ assert (query->packer == NULL);
+#endif
+ query->packer = sirinet_packer_new(1024);
+ if (query->packer == NULL)
+ {
+ MEM_ERR_RET
+ }
+ qp_add_type(query->packer, QP_MAP_OPEN);
+
+ QP_ADD_SUCCESS
+ log_info(MSG_SUCCESS_CREATE_GROUP, group_name);
+ qp_add_fmt_safe(query->packer, MSG_SUCCESS_CREATE_GROUP, group_name);
+
+ if (IS_MASTER)
+ {
+ siridb_query_forward(
+ handle,
+ SIRIDB_QUERY_FWD_UPDATE,
+ (sirinet_promises_cb) on_update_xxx_response,
+ 0);
+ }
+ else
+ {
+ SIRIPARSER_ASYNC_NEXT_NODE
+ }
+ }
+}
+
+static void exit_create_user(uv_async_t * handle)
+{
+ siridb_query_t * query = (siridb_query_t *) handle->data;
+ siridb_t * siridb = query->client->siridb;
+ siridb_user_t * user = ((query_alter_t *) query->data)->via.user;
+ cleri_node_t * user_node =
+ query->nodes->node->children->next->node;
+
+#if DEBUG
+ /* both name and packer should be NULL at this point */
+ assert(user->name == NULL);
+ assert(query->packer == NULL);
+#endif
+
+ MASTER_CHECK_ACCESSIBLE(siridb)
+
+ char name[user_node->len - 1];
+ strx_extract_string(name, user_node->str, user_node->len);
+
+ if (siridb_user_set_name(
+ siridb,
+ user,
+ name,
+ query->err_msg) ||
+ siridb_users_add_user(
+ siridb,
+ user,
+ query->err_msg))
+ {
+ siridb_query_send_error(handle, CPROTO_ERR_QUERY);
+ }
+ else
+ {
+ /* success, increment the user reference counter */
+ siridb_user_incref(user);
+
+#if DEBUG
+ assert (query->packer == NULL);
+#endif
+ query->packer = sirinet_packer_new(1024);
+
+ if (query->packer == NULL)
+ {
+ MEM_ERR_RET
+ }
+
+ qp_add_type(query->packer, QP_MAP_OPEN);
+
+ QP_ADD_SUCCESS
+
+ log_info(MSG_SUCCESS_CREATE_USER, user->name);
+ qp_add_fmt_safe(query->packer, MSG_SUCCESS_CREATE_USER, user->name);
+
+ if (IS_MASTER)
+ {
+ siridb_query_forward(
+ handle,
+ SIRIDB_QUERY_FWD_UPDATE,
+ (sirinet_promises_cb) on_update_xxx_response,
+ 0);
+ }
+ else
+ {
+ SIRIPARSER_ASYNC_NEXT_NODE
+ }
+ }
+}
+
+static void exit_drop_group(uv_async_t * handle)
+{
+ siridb_query_t * query = (siridb_query_t *) handle->data;
+ siridb_t * siridb = query->client->siridb;
+
+ MASTER_CHECK_ACCESSIBLE(siridb)
+
+ cleri_node_t * group_node =
+ query->nodes->node->children->next->node;
+
+ char name[group_node->len - 1];
+
+ strx_extract_string(name, group_node->str, group_node->len);
+
+ if (siridb_groups_drop_group(siridb->groups, name, query->err_msg))
+ {
+ siridb_query_send_error(handle, CPROTO_ERR_QUERY);
+ }
+ else
+ {
+ QP_ADD_SUCCESS
+ log_info(MSG_SUCCESS_DROP_GROUP, name);
+ qp_add_fmt_safe(query->packer, MSG_SUCCESS_DROP_GROUP, name);
+
+ if (IS_MASTER)
+ {
+ siridb_query_forward(
+ handle,
+ SIRIDB_QUERY_FWD_UPDATE,
+ (sirinet_promises_cb) on_update_xxx_response,
+ 0);
+ }
+ else
+ {
+ SIRIPARSER_ASYNC_NEXT_NODE
+ }
+ }
+}
+
+static void exit_drop_series(uv_async_t * handle)
+{
+ siridb_query_t * query = (siridb_query_t *) handle->data;
+ siridb_t * siridb = query->client->siridb;
+ query_drop_t * q_drop = (query_drop_t *) query->data;
+
+ MASTER_CHECK_ACCESSIBLE(siridb)
+
+ /*
+ * We transform or copy the references from imap to slist because we need
+ * this list for both filtering or performing the actual drop.
+ */
+ uv_mutex_lock(&siridb->series_mutex);
+
+ q_drop->slist = (q_drop->series_map == NULL) ?
+ imap_2slist_ref(siridb->series_map) :
+ imap_slist_pop(q_drop->series_map);
+
+ uv_mutex_unlock(&siridb->series_mutex);
+
+ if (q_drop->slist == NULL)
+ {
+ MEM_ERR_RET
+ }
+
+ if (q_drop->series_map != NULL)
+ {
+ /* now we can simply destroy the imap in case we had one */
+ imap_free(q_drop->series_map, NULL);
+ q_drop->series_map = NULL;
+ }
+
+ /*
+ * This function will be called twice when using a where statement.
+ * The second time the where_expr is NULL and the reason we do this is
+ * so that we can honor a correct drop threshold.
+ */
+ if (q_drop->where_expr != NULL)
+ {
+ /* create a new one */
+ q_drop->series_map = imap_new();
+
+ if (q_drop->series_map == NULL)
+ {
+ MEM_ERR_RET
+ }
+
+ uv_async_t * next = (uv_async_t *) malloc(sizeof(uv_async_t));
+
+ if (next == NULL)
+ {
+ MEM_ERR_RET
+ }
+
+ next->data = handle->data;
+
+ uv_async_init(
+ siri.loop,
+ next,
+ (uv_async_cb) async_filter_series);
+ uv_async_send(next);
+
+ uv_close((uv_handle_t *) handle, (uv_close_cb) free);
+
+ }
+ else
+ {
+ double percent = (double)
+ q_drop->slist->len / siridb->series_map->len;
+
+ if (IS_MASTER &&
+ q_drop->slist->len &&
+ (~q_drop->flags & QUERIES_IGNORE_DROP_THRESHOLD) &&
+ percent >= siridb->drop_threshold)
+ {
+ snprintf(query->err_msg,
+ SIRIDB_MAX_SIZE_ERR_MSG,
+ "This query would drop %0.2f%% of the series in pool %u. "
+ "Add \'set ignore_threshold true\' to the query "
+ "statement if you really want to do this.",
+ percent * 100,
+ siridb->server->pool);
+
+ siridb_query_send_error(handle, CPROTO_ERR_QUERY);
+ }
+ else
+ {
+ QP_ADD_SUCCESS
+
+ q_drop->n = q_drop->slist->len;
+
+ uv_async_t * next = (uv_async_t *) malloc(sizeof(uv_async_t));
+
+ if (next == NULL)
+ {
+ MEM_ERR_RET
+ }
+
+ next->data = handle->data;
+
+ uv_async_init(
+ siri.loop,
+ next,
+ (uv_async_cb) async_drop_series);
+ uv_async_send(next);
+
+ uv_close((uv_handle_t *) handle, (uv_close_cb) free);
+ }
+ }
+}
+
+static void exit_drop_server(uv_async_t * handle)
+{
+ siridb_query_t * query = (siridb_query_t *) handle->data;
+ siridb_t * siridb = query->client->siridb;
+ siridb_server_t * server = siridb_server_from_node(
+ siridb,
+ query->nodes->node->children->next->node->children->node,
+ query->err_msg);
+
+ MASTER_CHECK_REINDEXING(siridb)
+ MASTER_CHECK_ONLINE(siridb)
+
+ if (server == NULL)
+ {
+ siridb_query_send_error(handle, CPROTO_ERR_QUERY);
+ }
+ else if (siridb->pools->pool[server->pool].len == 1)
+ {
+ snprintf(
+ query->err_msg,
+ SIRIDB_MAX_SIZE_ERR_MSG,
+ "Cannot remove server '%s' because this is the only "
+ "server for pool %u",
+ server->name,
+ server->pool);
+ siridb_query_send_error(handle, CPROTO_ERR_QUERY);
+ }
+ else if (siridb->server == server || server->client != NULL)
+ {
+ snprintf(
+ query->err_msg,
+ SIRIDB_MAX_SIZE_ERR_MSG,
+ "Cannot remove server '%s' because the server is still "
+ "online. (stop SiriDB on this server if you really want "
+ "to remove the server)",
+ server->name);
+ siridb_query_send_error(handle, CPROTO_ERR_QUERY);
+ }
+ else
+ {
+ QP_ADD_SUCCESS
+ log_info(MSG_SUCCESS_DROP_SERVER, server->name);
+ qp_add_fmt_safe(query->packer, MSG_SUCCESS_DROP_SERVER, server->name);
+
+ if (IS_MASTER)
+ {
+ query->flags |= SIRIDB_QUERY_FLAG_REBUILD;
+ siridb_query_forward(
+ handle,
+ SIRIDB_QUERY_FWD_UPDATE,
+ (sirinet_promises_cb) on_update_xxx_response,
+ FLAG_ONLY_CHECK_ONLINE);
+ }
+ else
+ {
+ SIRIPARSER_ASYNC_NEXT_NODE
+ }
+
+ /*
+ * After calling this function, all references to the server
+ * object might be gone
+ */
+ if (siridb_server_drop(siridb, server))
+ {
+ log_critical("Cannot save servers to file");
+ }
+ }
+}
+
+static void exit_drop_shards(uv_async_t * handle)
+{
+ siridb_query_t * query = (siridb_query_t *) handle->data;
+ siridb_t * siridb = query->client->siridb;
+ query_drop_t * q_drop = (query_drop_t *) query->data;
+
+ MASTER_CHECK_ACCESSIBLE(siridb)
+
+ uv_mutex_lock(&siridb->shards_mutex);
+
+ q_drop->shards_list = imap_2slist_ref(siridb->shards);
+
+ uv_mutex_unlock(&siridb->shards_mutex);
+
+ if (q_drop->shards_list == NULL)
+ {
+ MEM_ERR_RET
+ }
+
+ if (q_drop->where_expr != NULL)
+ {
+ uint64_t duration;
+ siridb_shard_view_t vshard = {
+ .server=siridb->server
+ };
+ size_t dropped = 0;
+ size_t i;
+
+ for (i = 0; i < q_drop->shards_list->len; i++)
+ {
+ vshard.shard = (siridb_shard_t *) q_drop->shards_list->data[i];
+
+ /* set start and end properties */
+ duration = (vshard.shard->tp == SIRIDB_SHARD_TP_NUMBER) ?
+ siridb->duration_num : siridb->duration_log;
+
+ vshard.start = vshard.shard->id - vshard.shard->id % duration;
+ vshard.end = vshard.start + duration;
+
+ if (!cexpr_run(
+ q_drop->where_expr,
+ (cexpr_cb_t) siridb_shard_cexpr_cb,
+ &vshard))
+ {
+ siridb_shard_decref(vshard.shard);
+ dropped++;
+ }
+ else if (dropped)
+ {
+ q_drop->shards_list->data[i - dropped] = vshard.shard;
+ }
+ }
+
+ q_drop->shards_list->len -= dropped;
+ }
+
+ double percent = (double)
+ q_drop->shards_list->len / siridb->shards->len;
+
+ if (IS_MASTER &&
+ q_drop->shards_list->len &&
+ (~q_drop->flags & QUERIES_IGNORE_DROP_THRESHOLD) &&
+ percent >= siridb->drop_threshold)
+ {
+ snprintf(query->err_msg,
+ SIRIDB_MAX_SIZE_ERR_MSG,
+ "This query would drop %0.2f%% of the shards in pool %u. "
+ "Add \'set ignore_threshold true\' to the query "
+ "statement if you really want to do this.",
+ percent * 100,
+ siridb->server->pool);
+
+ siridb_query_send_error(handle, CPROTO_ERR_QUERY);
+ }
+ else
+ {
+ uv_async_t * next;
+
+ QP_ADD_SUCCESS
+
+ q_drop->n = q_drop->shards_list->len;
+
+ next = (uv_async_t *) malloc(sizeof(uv_async_t));
+
+ if (next == NULL)
+ {
+ MEM_ERR_RET
+ }
+
+ next->data = handle->data;
+
+ uv_async_init(
+ siri.loop,
+ next,
+ (uv_async_cb) async_drop_shards);
+ uv_async_send(next);
+
+ uv_close((uv_handle_t *) handle, (uv_close_cb) free);
+ }
+}
+
+static void exit_drop_user(uv_async_t * handle)
+{
+ siridb_query_t * query = (siridb_query_t *) handle->data;
+ siridb_t * siridb = query->client->siridb;
+
+ MASTER_CHECK_ACCESSIBLE(siridb)
+
+ cleri_node_t * user_node =
+ query->nodes->node->children->next->node;
+ char username[user_node->len - 1];
+
+ strx_extract_string(username, user_node->str, user_node->len);
+
+ if (siridb_users_drop_user(
+ siridb,
+ username,
+ query->err_msg))
+ {
+ siridb_query_send_error(handle, CPROTO_ERR_QUERY);
+ }
+ else
+ {
+ QP_ADD_SUCCESS
+ log_info(MSG_SUCCESS_DROP_USER, username);
+ qp_add_fmt_safe(query->packer, MSG_SUCCESS_DROP_USER, username);
+
+ if (IS_MASTER)
+ {
+ siridb_query_forward(
+ handle,
+ SIRIDB_QUERY_FWD_UPDATE,
+ (sirinet_promises_cb) on_update_xxx_response,
+ 0);
+ }
+ else
+ {
+ SIRIPARSER_ASYNC_NEXT_NODE
+ }
+ }
+}
+
+static void exit_grant_user(uv_async_t * handle)
+{
+ siridb_query_t * query = (siridb_query_t *) handle->data;
+ siridb_t * siridb = query->client->siridb;
+
+ if (siridb_users_save(siridb))
+ {
+ sprintf(query->err_msg, "Could not write users to file!");
+ log_critical(query->err_msg);
+ siridb_query_send_error(handle, CPROTO_ERR_QUERY);
+ return;
+ }
+
+#if DEBUG
+ assert (query->packer == NULL);
+#endif
+
+ query->packer = sirinet_packer_new(1024);
+
+ if (query->packer == NULL)
+ {
+ MEM_ERR_RET
+ }
+
+ qp_add_type(query->packer, QP_MAP_OPEN);
+
+ QP_ADD_SUCCESS
+ char * name = ((query_alter_t *) query->data)->via.user->name;
+ log_info(MSG_SUCCESS_GRANT_USER, name);
+ qp_add_fmt_safe(query->packer, MSG_SUCCESS_GRANT_USER, name);
+
+ if (IS_MASTER)
+ {
+ siridb_query_forward(
+ handle,
+ SIRIDB_QUERY_FWD_UPDATE,
+ (sirinet_promises_cb) on_update_xxx_response,
+ 0);
+ }
+ else
+ {
+ SIRIPARSER_ASYNC_NEXT_NODE
+ }
+}
+
+static void exit_help_xxx(uv_async_t * handle)
+{
+ siridb_query_t * query = (siridb_query_t *) handle->data;
+
+ if (query->data != NULL)
+ {
+#if DEBUG
+ assert (query->packer == NULL);
+#endif
+ const char * help = siri_help_get(
+ query->nodes->node->cl_obj->gid,
+ (const char *) query->data,
+ query->err_msg);
+
+ if (help == NULL)
+ {
+ siridb_query_send_error(handle, CPROTO_ERR_QUERY);
+ return;
+ }
+
+ query->packer = sirinet_packer_new(4096);
+
+ if (query->packer == NULL)
+ {
+ MEM_ERR_RET
+ }
+
+ qp_add_type(query->packer, QP_MAP_OPEN);
+ qp_add_raw(query->packer, (const unsigned char *) "help", 4);
+ qp_add_string(query->packer, help);
+
+ free(query->data);
+ query->data = NULL;
+ }
+ SIRIPARSER_ASYNC_NEXT_NODE
+}
+
+static void exit_list_groups(uv_async_t * handle)
+{
+ siridb_query_t * query = (siridb_query_t *) handle->data;
+ siridb_t * siridb = query->client->siridb;
+ query_list_t * q_list = (query_list_t *) query->data;
+
+ int is_local = (q_list->props == NULL);
+
+ /* if not is_local check for 'remote' columns */
+ if (!is_local)
+ {
+ is_local = 1;
+ size_t i;
+ for (i = 0; i < q_list->props->len; i++)
+ {
+ if (siridb_group_is_remote_prop(
+ *((uint32_t *) q_list->props->data[i])))
+ {
+ is_local = 0;
+ break;
+ }
+ }
+ }
+
+ /* if is_local, check if we use 'remote' props in where expression */
+ if (is_local && q_list->where_expr != NULL)
+ {
+ is_local = !cexpr_contains(
+ q_list->where_expr,
+ siridb_group_is_remote_prop);
+ }
+
+ if (is_local)
+ {
+ finish_list_groups(handle);
+ }
+ else
+ {
+ sirinet_pkg_t * pkg = sirinet_pkg_new(0, 0, BPROTO_REQ_GROUPS, NULL);
+
+ if (pkg != NULL)
+ {
+ siri_async_incref(handle);
+
+ query->nodes->cb = (uv_async_cb) finish_list_groups;
+
+ siridb_pools_send_pkg(
+ siridb,
+ pkg,
+ 0,
+ (sirinet_promises_cb) on_groups_response,
+ handle,
+ 0);
+ }
+ }
+}
+
+static void exit_list_pools(uv_async_t * handle)
+{
+ siridb_query_t * query = (siridb_query_t *) handle->data;
+ siridb_t * siridb = query->client->siridb;
+ query_list_t * q_list = (query_list_t *) query->data;
+ siridb_pool_t * pool = siridb->pools->pool + siridb->server->pool;
+ siridb_pool_walker_t wpool = {
+ .servers=pool->len,
+ .series=siridb->series->len,
+ .pool=siridb->server->pool
+ };
+ uint_fast16_t prop;
+ cexpr_t * where_expr = q_list->where_expr;
+
+ if (q_list->props == NULL)
+ {
+ q_list->props = slist_new(3);
+
+ if (q_list->props == NULL)
+ {
+ MEM_ERR_RET
+ }
+
+ slist_append(q_list->props, &GID_K_POOL);
+ slist_append(q_list->props, &GID_K_SERVERS);
+ slist_append(q_list->props, &GID_K_SERIES);
+ qp_add_raw(query->packer, (const unsigned char *) "pool", 4);
+ qp_add_raw(query->packer, (const unsigned char *) "servers", 7);
+ qp_add_raw(query->packer, (const unsigned char *) "series", 6);
+ }
+
+ qp_add_type(query->packer, QP_ARRAY_CLOSE);
+
+ qp_add_raw(query->packer, (const unsigned char *) "pools", 5);
+ qp_add_type(query->packer, QP_ARRAY_OPEN);
+
+ if ( q_list->limit &&
+ (where_expr == NULL || cexpr_run(
+ where_expr,
+ (cexpr_cb_t) siridb_pool_cexpr_cb,
+ &wpool)))
+ {
+ qp_add_type(query->packer, QP_ARRAY_OPEN);
+
+ for (prop = 0; prop < q_list->props->len; prop++)
+ {
+ switch(*((uint32_t *) q_list->props->data[prop]))
+ {
+ case CLERI_GID_K_POOL:
+ qp_add_int16(query->packer, wpool.pool);
+ break;
+ case CLERI_GID_K_SERVERS:
+ qp_add_int16(query->packer, wpool.servers);
+ break;
+ case CLERI_GID_K_SERIES:
+ qp_add_int64(query->packer, wpool.series);
+ break;
+ }
+ }
+
+ qp_add_type(query->packer, QP_ARRAY_CLOSE);
+ q_list->limit--;
+ }
+
+ if (IS_MASTER && q_list->limit)
+ {
+ /* we have not reached the limit, send the query to other pools */
+ siridb_query_forward(
+ handle,
+ SIRIDB_QUERY_FWD_POOLS,
+ (sirinet_promises_cb) on_list_xxx_response,
+ 0);
+ }
+ else
+ {
+ qp_add_type(query->packer, QP_ARRAY_CLOSE);
+
+ SIRIPARSER_ASYNC_NEXT_NODE
+ }
+}
+
+static void exit_list_series(uv_async_t * handle)
+{
+ siridb_query_t * query = (siridb_query_t *) handle->data;
+ query_list_t * q_list = (query_list_t *) query->data;
+ siridb_t * siridb = query->client->siridb;
+
+ if (q_list->props == NULL)
+ {
+ q_list->props = slist_new(1);
+
+ if (q_list->props == NULL)
+ {
+ MEM_ERR_RET
+ }
+
+ slist_append(q_list->props, &GID_K_NAME);
+ qp_add_raw(query->packer, (const unsigned char *) "name", 4);
+ }
+
+ qp_add_type(query->packer, QP_ARRAY_CLOSE);
+
+ qp_add_raw(query->packer, (const unsigned char *) "series", 6);
+ qp_add_type(query->packer, QP_ARRAY_OPEN);
+
+ uv_mutex_lock(&siridb->series_mutex);
+
+ q_list->slist = imap_2slist_ref((q_list->series_map == NULL) ?
+ siridb->series_map : q_list->series_map);
+
+ uv_mutex_unlock(&siridb->series_mutex);
+
+ if (q_list->slist == NULL)
+ {
+ MEM_ERR_RET;
+ }
+
+ uv_async_t * next = (uv_async_t *) malloc(sizeof(uv_async_t));
+
+ if (next == NULL)
+ {
+ MEM_ERR_RET
+ }
+
+ next->data = handle->data;
+
+ uv_async_init(
+ siri.loop,
+ next,
+ (uv_async_cb) async_list_series);
+ uv_async_send(next);
+
+ uv_close((uv_handle_t *) handle, (uv_close_cb) free);
+}
+
+static void exit_list_servers(uv_async_t * handle)
+{
+ siridb_query_t * query = (siridb_query_t *) handle->data;
+ siridb_t * siridb = query->client->siridb;
+
+ query_list_t * q_list = (query_list_t *) query->data;
+ cexpr_t * where_expr = q_list->where_expr;
+ int is_local = IS_MASTER;
+
+ /* if is_local, check if we need ask for 'remote' columns */
+ if (is_local && q_list->props != NULL)
+ {
+ size_t i;
+ for (i = 0; i < q_list->props->len; i++)
+ {
+ if (siridb_server_is_remote_prop(
+ *((uint32_t *) q_list->props->data[i])))
+ {
+ is_local = 0;
+ break;
+ }
+ }
+ }
+
+ /* if is_local, check if we use 'remote' props in where expression */
+ if (is_local && where_expr != NULL)
+ {
+ is_local = !cexpr_contains(where_expr, siridb_server_is_remote_prop);
+ }
+
+ if (q_list->props == NULL)
+ {
+ q_list->props = slist_new(5);
+
+ if (q_list->props == NULL)
+ {
+ MEM_ERR_RET
+ }
+
+ slist_append(q_list->props, &GID_K_NAME);
+ slist_append(q_list->props, &GID_K_POOL);
+ slist_append(q_list->props, &GID_K_VERSION);
+ slist_append(q_list->props, &GID_K_ONLINE);
+ slist_append(q_list->props, &GID_K_STATUS);
+ qp_add_raw(query->packer, (const unsigned char *) "name", 4);
+ qp_add_raw(query->packer, (const unsigned char *) "pool", 4);
+ qp_add_raw(query->packer, (const unsigned char *) "version", 7);
+ qp_add_raw(query->packer, (const unsigned char *) "online", 6);
+ qp_add_raw(query->packer, (const unsigned char *) "status", 6);
+ }
+
+ qp_add_type(query->packer, QP_ARRAY_CLOSE);
+
+ qp_add_raw(query->packer, (const unsigned char *) "servers", 7);
+ qp_add_type(query->packer, QP_ARRAY_OPEN);
+
+ if (is_local)
+ {
+ llist_walkn(
+ siridb->servers,
+ &q_list->limit,
+ (llist_cb) siridb_servers_list,
+ handle);
+ }
+ else
+ {
+ q_list->limit -= siridb_servers_list(siridb->server, handle);
+ }
+
+
+ if (IS_MASTER && !is_local && q_list->limit)
+ {
+ siridb_query_forward(
+ handle,
+ SIRIDB_QUERY_FWD_SERVERS,
+ (sirinet_promises_cb) on_list_xxx_response,
+ 0);
+ }
+ else
+ {
+ qp_add_type(query->packer, QP_ARRAY_CLOSE);
+ SIRIPARSER_ASYNC_NEXT_NODE
+ }
+}
+
+static void exit_list_shards(uv_async_t * handle)
+{
+ siridb_query_t * query = (siridb_query_t *) handle->data;
+ siridb_t * siridb = query->client->siridb;
+
+ query_list_t * q_list = (query_list_t *) query->data;
+ uint_fast16_t prop;
+ uint64_t duration;
+ cexpr_t * where_expr = q_list->where_expr;
+ siridb_shard_view_t vshard = {
+ .server=siridb->server
+ };
+ size_t i;
+ slist_t * shards_list;
+
+ uv_mutex_lock(&siridb->shards_mutex);
+
+ shards_list = imap_2slist_ref(siridb->shards);
+
+ uv_mutex_unlock(&siridb->shards_mutex);
+
+ if (shards_list == NULL)
+ {
+ MEM_ERR_RET
+ }
+
+ if (q_list->props == NULL)
+ {
+ q_list->props = slist_new(5);
+
+ if (q_list->props == NULL)
+ {
+ MEM_ERR_RET
+ }
+
+ slist_append(q_list->props, &GID_K_SID);
+ slist_append(q_list->props, &GID_K_POOL);
+ slist_append(q_list->props, &GID_K_SERVER);
+ slist_append(q_list->props, &GID_K_START);
+ slist_append(q_list->props, &GID_K_END);
+ qp_add_raw(query->packer, (const unsigned char *) "sid", 3);
+ qp_add_raw(query->packer, (const unsigned char *) "pool", 4);
+ qp_add_raw(query->packer, (const unsigned char *) "server", 6);
+ qp_add_raw(query->packer, (const unsigned char *) "start", 5);
+ qp_add_raw(query->packer, (const unsigned char *) "end", 3);
+ }
+
+ qp_add_type(query->packer, QP_ARRAY_CLOSE);
+
+ qp_add_raw(query->packer, (const unsigned char *) "shards", 6);
+ qp_add_type(query->packer, QP_ARRAY_OPEN);
+
+ for (i = 0; i < shards_list->len; i++)
+ {
+ vshard.shard = (siridb_shard_t *) shards_list->data[i];
+
+ /* set start and end properties */
+ duration = (vshard.shard->tp == SIRIDB_SHARD_TP_NUMBER) ?
+ siridb->duration_num : siridb->duration_log;
+ vshard.start = vshard.shard->id - vshard.shard->id % duration;
+ vshard.end = vshard.start + duration;
+
+ if (q_list->limit && (where_expr == NULL || cexpr_run(
+ where_expr,
+ (cexpr_cb_t) siridb_shard_cexpr_cb,
+ &vshard)))
+ {
+ qp_add_type(query->packer, QP_ARRAY_OPEN);
+
+ for (prop = 0; prop < q_list->props->len; prop++)
+ {
+ switch(*((uint32_t *) q_list->props->data[prop]))
+ {
+ case CLERI_GID_K_SID:
+ qp_add_int64(query->packer, vshard.shard->id);
+ break;
+ case CLERI_GID_K_POOL:
+ qp_add_int16(query->packer, vshard.server->pool);
+ break;
+ case CLERI_GID_K_SIZE:
+ qp_add_int64(query->packer, vshard.shard->len);
+ break;
+ case CLERI_GID_K_START:
+ qp_add_int64(query->packer, vshard.start);
+ break;
+ case CLERI_GID_K_END:
+ qp_add_int64(query->packer, vshard.end);
+ break;
+ case CLERI_GID_K_TYPE:
+ qp_add_string(
+ query->packer,
+ shard_type_map[vshard.shard->tp]);
+ break;
+ case CLERI_GID_K_SERVER:
+ qp_add_string(query->packer, vshard.server->name);
+ break;
+ case CLERI_GID_K_STATUS:
+ {
+ char buffer[SIRIDB_SHARD_STATUS_STR_MAX];
+ int n = siridb_shard_status(buffer, vshard.shard);
+ qp_add_raw(
+ query->packer,
+ (const unsigned char *) buffer,
+ n);
+ }
+ break;
+ }
+ }
+ qp_add_type(query->packer, QP_ARRAY_CLOSE);
+
+ q_list->limit--;
+ }
+
+ siridb_shard_decref(vshard.shard);
+ }
+
+ slist_free(shards_list);
+
+ if (IS_MASTER && q_list->limit)
+ {
+ /* we have not reached the limit, send the query to other pools */
+ siridb_query_forward(
+ handle,
+ SIRIDB_QUERY_FWD_SERVERS,
+ (sirinet_promises_cb) on_list_xxx_response,
+ 0);
+ }
+ else
+ {
+ qp_add_type(query->packer, QP_ARRAY_CLOSE);
+
+ SIRIPARSER_ASYNC_NEXT_NODE
+ }
+}
+
+static void exit_list_users(uv_async_t * handle)
+{
+ siridb_query_t * query = (siridb_query_t *) handle->data;
+ siridb_t * siridb = query->client->siridb;
+
+ llist_node_t * node = siridb->users->first;
+ slist_t * props = ((query_list_t *) query->data)->props;
+ cexpr_cb_t cb = (cexpr_cb_t) siridb_user_cexpr_cb;
+ query_list_t * q_list = (query_list_t *) query->data;
+ cexpr_t * where_expr = q_list->where_expr;
+ size_t i;
+ siridb_user_t * user;
+
+ if (props == NULL)
+ {
+ qp_add_raw(query->packer, (const unsigned char *) "name", 4);
+ qp_add_raw(query->packer, (const unsigned char *) "access", 6);
+ }
+
+ qp_add_type(query->packer, QP_ARRAY_CLOSE);
+
+ qp_add_raw(query->packer, (const unsigned char *) "users", 5);
+ qp_add_type(query->packer, QP_ARRAY_OPEN);
+
+ while (node != NULL && q_list->limit)
+ {
+ user = node->data;
+
+ if (where_expr == NULL || cexpr_run(where_expr, cb, user))
+ {
+ q_list->limit--;
+
+ qp_add_type(query->packer, QP_ARRAY_OPEN);
+
+ if (props == NULL)
+ {
+ siridb_user_prop(user, query->packer, CLERI_GID_K_NAME);
+ siridb_user_prop(user, query->packer, CLERI_GID_K_ACCESS);
+ }
+ else
+ {
+ for (i = 0; i < props->len; i++)
+ {
+ siridb_user_prop(
+ user,
+ query->packer,
+ *((uint32_t *) props->data[i]));
+ }
+ }
+
+ qp_add_type(query->packer, QP_ARRAY_CLOSE);
+
+ }
+ node = node->next;
+ }
+ qp_add_type(query->packer, QP_ARRAY_CLOSE);
+
+ SIRIPARSER_ASYNC_NEXT_NODE
+}
+
+static void exit_revoke_user(uv_async_t * handle)
+{
+ siridb_query_t * query = (siridb_query_t *) handle->data;
+ siridb_t * siridb = query->client->siridb;
+
+ if (siridb_users_save(siridb))
+ {
+ sprintf(query->err_msg, "Could not write users to file!");
+ log_critical(query->err_msg);
+ siridb_query_send_error(handle, CPROTO_ERR_QUERY);
+ return;
+ }
+
+#if DEBUG
+ assert (query->packer == NULL);
+#endif
+
+ query->packer = sirinet_packer_new(1024);
+
+ if (query->packer == NULL)
+ {
+ MEM_ERR_RET
+ }
+
+ qp_add_type(query->packer, QP_MAP_OPEN);
+
+ QP_ADD_SUCCESS
+ char * name = ((query_alter_t *) query->data)->via.user->name;
+ log_info(MSG_SUCCESS_REVOKE_USER, name);
+ qp_add_fmt_safe(query->packer, MSG_SUCCESS_REVOKE_USER, name);
+
+ if (IS_MASTER)
+ {
+ siridb_query_forward(
+ handle,
+ SIRIDB_QUERY_FWD_UPDATE,
+ (sirinet_promises_cb) on_update_xxx_response,
+ 0);
+ }
+ else
+ {
+ SIRIPARSER_ASYNC_NEXT_NODE
+ }
+}
+
+static void exit_series_match(uv_async_t * handle)
+{
+ siridb_query_t * query = (siridb_query_t *) handle->data;
+ query_wrapper_t * q_wrapper = (query_wrapper_t *) query->data;
+
+ if (q_wrapper->tp == QUERIES_SELECT)
+ {
+ query_select_t * q_select = (query_select_t *) q_wrapper;
+ if ((q_select->flags & QUERIES_SKIP_GET_POINTS) &&
+ (q_select->start_ts != NULL || q_select->end_ts != NULL))
+ {
+ q_select->flags &= ~QUERIES_SKIP_GET_POINTS;
+ }
+
+ if ((~q_select->flags & QUERIES_SKIP_GET_POINTS) &&
+ q_select->nselects > 1)
+ {
+ /* We have more than one select request, let's use points caching.
+ * (Not critical, everything works if points_map is NULL) */
+ q_select->points_map = imap_new();
+ }
+ }
+
+ SIRIPARSER_ASYNC_NEXT_NODE
+}
+
+static void exit_select_aggregate(uv_async_t * handle)
+{
+ siridb_query_t * query = (siridb_query_t *) handle->data;
+ query_select_t * q_select = (query_select_t *) query->data;
+
+ if (q_select->where_expr != NULL)
+ {
+ /* we transform the references from imap to slist */
+ q_select->slist = imap_slist_pop(q_select->series_map);
+
+ if (q_select->slist == NULL)
+ {
+ MEM_ERR_RET
+ }
+
+ /* now we can simply destroy the imap */
+ imap_free(q_select->series_map, NULL);
+
+ /* create a new one */
+ q_select->series_map = imap_new();
+
+ if (q_select->series_map == NULL)
+ {
+ MEM_ERR_RET
+ }
+
+ uv_async_t * next =
+ (uv_async_t *) malloc(sizeof(uv_async_t));
+
+ if (next == NULL)
+ {
+ MEM_ERR_RET
+ }
+
+ next->data = handle->data;
+
+ uv_async_init(
+ siri.loop,
+ next,
+ (uv_async_cb) async_filter_series);
+ uv_async_send(next);
+
+ uv_close((uv_handle_t *) handle, (uv_close_cb) free);
+
+ }
+ else if (siridb_presuf_add(&q_select->presuf, query->nodes->node) == NULL)
+ {
+ MEM_ERR_RET
+ }
+ else
+ {
+ q_select->nselects--;
+
+ if (!siridb_presuf_is_unique(q_select->presuf))
+ {
+ snprintf(query->err_msg,
+ SIRIDB_MAX_SIZE_ERR_MSG,
+ "When using multiple select methods, add a prefix "
+ "and/or suffix to the selection to make them unique.");
+ siridb_query_send_error(handle, CPROTO_ERR_QUERY);
+ }
+ else
+ {
+ if (q_select->merge_as != NULL)
+ {
+ slist_t * plist = slist_new(SLIST_DEFAULT_SIZE);
+
+ if (plist == NULL || ct_add(
+ q_select->result,
+ siridb_presuf_name(
+ q_select->presuf,
+ q_select->merge_as,
+ strlen(q_select->merge_as)),
+ plist))
+ {
+ sprintf(query->err_msg,
+ "Error while merging points. Make sure the "
+ "destination series name is valid.");
+ slist_free(plist);
+ siridb_query_send_error(handle, CPROTO_ERR_QUERY);
+ return;
+ }
+ }
+
+ if (q_select->series_map->len)
+ {
+ q_select->alist = siridb_aggregate_list(
+ query->nodes->node->children->node->children,
+ query->err_msg);
+ if (q_select->alist == NULL)
+ {
+ siridb_query_send_error(handle, CPROTO_ERR_QUERY);
+ return;
+ }
+ q_select->slist = imap_2slist_ref(q_select->series_map);
+
+ if (q_select->slist == NULL)
+ {
+ MEM_ERR_RET
+ }
+
+ uv_async_t * next =
+ (uv_async_t *) malloc(sizeof(uv_async_t));
+
+ if (next == NULL)
+ {
+ MEM_ERR_RET
+ }
+
+ next->data = handle->data;
+
+ uv_async_init(
+ siri.loop,
+ next,
+ (uv_async_cb) (
+ (q_select->flags & QUERIES_SKIP_GET_POINTS) ?
+ async_no_points_aggregate :
+ async_select_aggregate));
+ uv_async_send(next);
+
+ uv_close((uv_handle_t *) handle, (uv_close_cb) free);
+ }
+ else
+ {
+ SIRIPARSER_ASYNC_NEXT_NODE
+ }
+ }
+ }
+}
+
+static void exit_select_stmt(uv_async_t * handle)
+{
+ siridb_query_t * query = (siridb_query_t *) handle->data;
+ query_select_t * q_select = (query_select_t *) query->data;
+
+ if (IS_MASTER)
+ {
+ if (q_select->pmap == NULL || q_select->pmap->len)
+ {
+ /* we have not reached the limit, send the query to other pools */
+ siridb_query_forward(
+ handle,
+ (q_select->pmap == NULL) ?
+ SIRIDB_QUERY_FWD_POOLS :
+ SIRIDB_QUERY_FWD_SOME_POOLS,
+ (sirinet_promises_cb) on_select_response,
+ 0);
+ }
+ else
+ {
+ uv_work_t * work = (uv_work_t *) malloc(sizeof(uv_work_t));
+ if (work == NULL)
+ {
+ MEM_ERR_RET
+ }
+
+ uv_async_t * next = (uv_async_t *) malloc(sizeof(uv_async_t));
+ if (next == NULL)
+ {
+ free(work);
+ MEM_ERR_RET
+ }
+
+ uv_close((uv_handle_t *) handle, (uv_close_cb) free);
+
+ handle = next;
+ handle->data = query;
+ siridb_nodes_next(&query->nodes);
+
+ uv_async_init(
+ siri.loop,
+ handle,
+ (query->nodes == NULL) ?
+ (uv_async_cb) siridb_send_query_result :
+ (uv_async_cb) query->nodes->cb);
+
+ siri_async_incref(handle);
+ work->data = handle;
+ uv_queue_work(
+ siri.loop,
+ work,
+ &master_select_work,
+ &master_select_work_finish);
+ }
+ }
+ else
+ {
+ if (qp_add_raw(query->packer, (const unsigned char *) "select", 6) ||
+ qp_add_type(query->packer, QP_MAP_OPEN) ||
+ ct_items(
+ q_select->result,
+ (q_select->merge_as == NULL) ?
+ (ct_item_cb) &items_select_other
+ :
+ (ct_item_cb) &items_select_other_merge,
+ handle) ||
+ qp_add_type(query->packer, QP_MAP_CLOSE))
+ {
+ MEM_ERR_RET
+ }
+ else
+ {
+ SIRIPARSER_ASYNC_NEXT_NODE
+ }
+ }
+}
+
+static void exit_set_address(uv_async_t * handle)
+{
+ siridb_query_t * query = (siridb_query_t *) handle->data;
+ siridb_server_t * server = ((query_alter_t *) query->data)->via.server;
+ cleri_node_t * node = query->nodes->node->children->next->next->node;
+ siridb_t * siridb = query->client->siridb;
+
+ if (siridb->server == server || server->client != NULL)
+ {
+ sprintf(query->err_msg, MSG_ERR_SERVER_ADDRESS);
+ siridb_query_send_error(handle, CPROTO_ERR_QUERY);
+ return;
+ }
+
+ char address[node->len - 1];
+ strx_extract_string(address, node->str, node->len);
+
+ int rc;
+ rc = siridb_server_update_address(siridb, server, address, server->port);
+ switch (rc)
+ {
+ case -1:
+ sprintf(query->err_msg, "Error while updating server address");
+ siridb_query_send_error(handle, CPROTO_ERR_QUERY);
+ break;
+
+ case 0:
+ snprintf(query->err_msg,
+ SIRIDB_MAX_SIZE_ERR_MSG,
+ "Server address is already set to '%s'",
+ server->address);
+ siridb_query_send_error(handle, CPROTO_ERR_QUERY);
+ break;
+
+ case 1:
+ QP_ADD_SUCCESS
+ qp_add_fmt_safe(query->packer,
+ MSG_SUCCESS_SET_ADDR_PORT,
+ server->name);
+ SIRIPARSER_ASYNC_NEXT_NODE
+ break;
+ }
+}
+
+static void exit_set_backup_mode(uv_async_t * handle)
+{
+ siridb_query_t * query = (siridb_query_t *) handle->data;
+ siridb_t * siridb = query->client->siridb;
+
+#if DEBUG
+ assert (query->data != NULL);
+ assert (IS_MASTER);
+#endif
+
+ siridb_server_t * server = ((query_alter_t *) query->data)->via.server;
+
+ int backup_mode = query->nodes->node->children->next->next->node->
+ children->node->cl_obj->gid == CLERI_GID_K_TRUE;
+
+ if (backup_mode ^ ((server->flags & SERVER_FLAG_BACKUP_MODE) != 0))
+ {
+ QP_ADD_SUCCESS
+ qp_add_fmt_safe(query->packer,
+ MSG_SUCCES_SET_BACKUP_MODE,
+ (backup_mode) ? "enabled" : "disabled",
+ server->name);
+
+ if (server == siridb->server)
+ {
+ if (backup_mode)
+ {
+ if (siri_backup_enable(&siri, siridb))
+ {
+ MEM_ERR_RET
+ }
+ }
+ else
+ {
+ if (siri_backup_disable(&siri, siridb))
+ {
+ MEM_ERR_RET
+ }
+ }
+
+ SIRIPARSER_ASYNC_NEXT_NODE
+ }
+ else
+ {
+ if (siridb_server_is_online(server))
+ {
+ sirinet_pkg_t * pkg = sirinet_pkg_new(
+ 0,
+ 0,
+ (backup_mode) ?
+ BPROTO_ENABLE_BACKUP_MODE :
+ BPROTO_DISABLE_BACKUP_MODE,
+ NULL);
+
+ if (pkg == NULL)
+ {
+ MEM_ERR_RET
+ }
+
+ /* handle will be bound to a timer so we should increment */
+ siri_async_incref(handle);
+
+ if (siridb_server_send_pkg(
+ server,
+ pkg,
+ 0,
+ on_ack_response,
+ handle,
+ 0))
+ {
+ /*
+ * signal is raised and 'on_ack_response' will not be
+ * called
+ */
+ free(pkg);
+ siri_async_decref(&handle);
+ MEM_ERR_RET
+ }
+ }
+ else
+ {
+ snprintf(query->err_msg,
+ SIRIDB_MAX_SIZE_ERR_MSG,
+ "Cannot %s backup mode, '%s' is currently unavailable",
+ (backup_mode) ? "enable" : "disable",
+ server->name);
+ siridb_query_send_error(handle, CPROTO_ERR_QUERY);
+ }
+ }
+ }
+ else
+ {
+ snprintf(query->err_msg,
+ SIRIDB_MAX_SIZE_ERR_MSG,
+ "Backup mode is already %s on '%s'.",
+ (backup_mode) ? "enabled" : "disabled",
+ server->name);
+ siridb_query_send_error(handle, CPROTO_ERR_QUERY);
+ }
+}
+
+static void exit_set_drop_threshold(uv_async_t * handle)
+{
+ siridb_query_t * query = (siridb_query_t *) handle->data;
+ siridb_t * siridb = query->client->siridb;
+
+ MASTER_CHECK_ACCESSIBLE(siridb)
+
+ cleri_node_t * node = query->nodes->node->children->next->next->node;
+
+ double drop_threshold = strx_to_double(node->str, node->len);
+
+ if (drop_threshold < 0.0 || drop_threshold > 1.0)
+ {
+ snprintf(query->err_msg,
+ SIRIDB_MAX_SIZE_ERR_MSG,
+ "Drop threshold should be a value between or "
+ "equal to 0 and 1.0 but got %0.3f",
+ drop_threshold);
+ siridb_query_send_error(handle, CPROTO_ERR_QUERY);
+ }
+ else
+ {
+ double old = siridb->drop_threshold;
+ siridb->drop_threshold = drop_threshold;
+ if (siridb_save(siridb))
+ {
+ snprintf(query->err_msg,
+ SIRIDB_MAX_SIZE_ERR_MSG,
+ "Error while saving database changes!");
+ siridb_query_send_error(handle, CPROTO_ERR_QUERY);
+ }
+ else
+ {
+ QP_ADD_SUCCESS
+
+ log_info(
+ MSG_SUCCESS_SET_DROP_THRESHOLD,
+ old,
+ siridb->drop_threshold);
+
+ qp_add_fmt_safe(query->packer,
+ MSG_SUCCESS_SET_DROP_THRESHOLD,
+ old,
+ siridb->drop_threshold);
+
+ if (IS_MASTER)
+ {
+ siridb_query_forward(
+ handle,
+ SIRIDB_QUERY_FWD_UPDATE,
+ (sirinet_promises_cb) on_update_xxx_response,
+ 0);
+ }
+ else
+ {
+ SIRIPARSER_ASYNC_NEXT_NODE
+ }
+ }
+ }
+}
+
+static void exit_set_list_limit(uv_async_t * handle)
+{
+ siridb_query_t * query = (siridb_query_t *) handle->data;
+ siridb_t * siridb = query->client->siridb;
+
+ MASTER_CHECK_ACCESSIBLE(siridb)
+ MASTER_CHECK_VERSION(siridb, "2.0.17")
+
+ cleri_node_t * node = query->nodes->node->children->next->next->node;
+
+ uint64_t limit = strx_to_uint64(node->str, node->len);
+
+ if (limit < 1000 || limit >= 4294967296)
+ {
+ snprintf(query->err_msg,
+ SIRIDB_MAX_SIZE_ERR_MSG,
+ "List limit should be a value greater than or equal to 1000 "
+ "and smaller than 4294967296 but got %" PRIu64,
+ limit);
+ siridb_query_send_error(handle, CPROTO_ERR_QUERY);
+ }
+ else
+ {
+ uint32_t old = siridb->list_limit;
+ siridb->list_limit = (uint32_t) limit;
+
+ if (siridb_save(siridb))
+ {
+ snprintf(query->err_msg,
+ SIRIDB_MAX_SIZE_ERR_MSG,
+ "Error while saving database changes!");
+ siridb_query_send_error(handle, CPROTO_ERR_QUERY);
+ }
+ else
+ {
+ QP_ADD_SUCCESS
+
+ log_info(
+ MSG_SUCCESS_SET_LIST_LIMIT,
+ old,
+ siridb->list_limit);
+
+ qp_add_fmt_safe(query->packer,
+ MSG_SUCCESS_SET_LIST_LIMIT,
+ old,
+ siridb->list_limit);
+
+ if (IS_MASTER)
+ {
+ siridb_query_forward(
+ handle,
+ SIRIDB_QUERY_FWD_UPDATE,
+ (sirinet_promises_cb) on_update_xxx_response,
+ 0);
+ }
+ else
+ {
+ SIRIPARSER_ASYNC_NEXT_NODE
+ }
+ }
+ }
+}
+
+static void exit_set_log_level(uv_async_t * handle)
+{
+ siridb_query_t * query = (siridb_query_t *) handle->data;
+ query_alter_t * q_alter = (query_alter_t *) query->data;
+ siridb_t * siridb = query->client->siridb;
+
+#if DEBUG
+ assert (query->data != NULL);
+#endif
+
+ cleri_node_t * node =
+ query->nodes->node->children->next->next->node->children->node;
+
+ int log_level;
+
+ switch (node->cl_obj->gid)
+ {
+ case CLERI_GID_K_DEBUG:
+ log_level = LOGGER_DEBUG;
+ break;
+ case CLERI_GID_K_INFO:
+ log_level = LOGGER_INFO;
+ break;
+ case CLERI_GID_K_WARNING:
+ log_level = LOGGER_WARNING;
+ break;
+ case CLERI_GID_K_ERROR:
+ log_level = LOGGER_ERROR;
+ break;
+ case CLERI_GID_K_CRITICAL:
+ log_level = LOGGER_CRITICAL;
+ break;
+ default:
+ assert (0);
+ break;
+ }
+
+ if (q_alter->alter_tp == QUERY_ALTER_SERVERS)
+ {
+ /*
+ * alter_servers
+ */
+ cexpr_t * where_expr = ((query_list_t *) query->data)->where_expr;
+ siridb_server_walker_t wserver = {
+ .server=siridb->server,
+ .siridb=siridb
+ };
+
+ if (where_expr == NULL || cexpr_run(
+ where_expr,
+ (cexpr_cb_t) siridb_server_cexpr_cb,
+ &wserver))
+ {
+ logger_set_level(log_level);
+ q_alter->n++;
+ }
+
+ if (IS_MASTER)
+ {
+ /*
+ * Hide log level information so we can later create an appropriate
+ * message.
+ */
+ q_alter->n += log_level << 16;
+ siridb_query_forward(
+ handle,
+ SIRIDB_QUERY_FWD_SERVERS,
+ (sirinet_promises_cb) on_alter_xxx_response,
+ 0);
+ }
+ else
+ {
+ qp_add_raw(query->packer, (const unsigned char *) "servers", 7);
+ qp_add_int64(query->packer, q_alter->n);
+ SIRIPARSER_ASYNC_NEXT_NODE
+ }
+ }
+ else
+ {
+ /*
+ * alter_server
+ *
+ * we can set the success message, we just ignore the message in case
+ * an error occurs.
+ */
+ siridb_server_t * server = q_alter->via.server;
+
+ QP_ADD_SUCCESS
+ qp_add_fmt_safe(query->packer,
+ MSG_SUCCES_SET_LOG_LEVEL,
+ logger_level_name(log_level),
+ server->name);
+
+ if (server == siridb->server)
+ {
+ logger_set_level(log_level);
+
+ SIRIPARSER_ASYNC_NEXT_NODE
+ }
+ else
+ {
+ QP_PACK_INT16(buffer, log_level)
+
+ if (siridb_server_is_online(server))
+ {
+ sirinet_pkg_t * pkg = sirinet_pkg_new(
+ 0,
+ 3,
+ BPROTO_LOG_LEVEL_UPDATE,
+ buffer);
+ if (pkg != NULL)
+ {
+ /* handle will be bound to a timer so we should increment */
+ siri_async_incref(handle);
+ if (siridb_server_send_pkg(
+ server,
+ pkg,
+ 0,
+ on_ack_response,
+ handle,
+ 0))
+ {
+ /*
+ * signal is raised and 'on_ack_response' will not be
+ * called
+ */
+ free(pkg);
+ siri_async_decref(&handle);
+ }
+ }
+ }
+ else
+ {
+ snprintf(query->err_msg,
+ SIRIDB_MAX_SIZE_ERR_MSG,
+ "Cannot set log level, '%s' is currently unavailable",
+ server->name);
+ siridb_query_send_error(handle, CPROTO_ERR_QUERY);
+ }
+ }
+ }
+}
+
+static void exit_set_port(uv_async_t * handle)
+{
+ siridb_query_t * query = (siridb_query_t *) handle->data;
+ siridb_server_t * server = ((query_alter_t *) query->data)->via.server;
+ cleri_node_t * node = query->nodes->node->children->next->next->node;
+ siridb_t * siridb = query->client->siridb;
+
+ if (siridb->server == server || server->client != NULL)
+ {
+ sprintf(query->err_msg, MSG_ERR_SERVER_ADDRESS);
+ siridb_query_send_error(handle, CPROTO_ERR_QUERY);
+ return;
+ }
+
+
+ uint64_t port = strx_to_uint64(node->str, node->len);
+
+ if (port > 65535)
+ {
+ sprintf(query->err_msg,
+ "Server port must be a value between 0 and 65535");
+ siridb_query_send_error(handle, CPROTO_ERR_QUERY);
+ }
+ else
+ {
+ int rc;
+ rc = siridb_server_update_address(siridb, server, server->address, port);
+ switch (rc)
+ {
+ case -1:
+ sprintf(query->err_msg, "Error while updating server address");
+ siridb_query_send_error(handle, CPROTO_ERR_QUERY);
+ break;
+
+ case 0:
+ snprintf(query->err_msg,
+ SIRIDB_MAX_SIZE_ERR_MSG,
+ "Server port is already set to '%u'",
+ server->port);
+ siridb_query_send_error(handle, CPROTO_ERR_QUERY);
+ break;
+
+ case 1:
+ QP_ADD_SUCCESS
+ qp_add_fmt_safe(query->packer,
+ MSG_SUCCESS_SET_ADDR_PORT,
+ server->name);
+ SIRIPARSER_ASYNC_NEXT_NODE
+ break;
+ }
+ }
+}
+
+static void exit_set_select_points_limit(uv_async_t * handle)
+{
+ siridb_query_t * query = (siridb_query_t *) handle->data;
+ siridb_t * siridb = query->client->siridb;
+
+ MASTER_CHECK_ACCESSIBLE(siridb)
+ MASTER_CHECK_VERSION(siridb, "2.0.17")
+
+ cleri_node_t * node = query->nodes->node->children->next->next->node;
+
+ uint64_t limit = strx_to_uint64(node->str, node->len);
+
+ if (limit < 1 || limit >= 4294967296)
+ {
+ snprintf(query->err_msg,
+ SIRIDB_MAX_SIZE_ERR_MSG,
+ "Select points limit should be a value greater than 0 "
+ "and smaller than 4294967296 but got %" PRIu64,
+ limit);
+ siridb_query_send_error(handle, CPROTO_ERR_QUERY);
+ }
+ else
+ {
+ uint32_t old = siridb->select_points_limit;
+ siridb->select_points_limit = (uint32_t) limit;
+
+ if (siridb_save(siridb))
+ {
+ snprintf(query->err_msg,
+ SIRIDB_MAX_SIZE_ERR_MSG,
+ "Error while saving database changes!");
+ siridb_query_send_error(handle, CPROTO_ERR_QUERY);
+ }
+ else
+ {
+ QP_ADD_SUCCESS
+
+ log_info(
+ MSG_SUCCESS_SET_SELECT_POINTS_LIMIT,
+ old,
+ siridb->select_points_limit);
+
+ qp_add_fmt_safe(query->packer,
+ MSG_SUCCESS_SET_SELECT_POINTS_LIMIT,
+ old,
+ siridb->select_points_limit);
+
+ if (IS_MASTER)
+ {
+ siridb_query_forward(
+ handle,
+ SIRIDB_QUERY_FWD_UPDATE,
+ (sirinet_promises_cb) on_update_xxx_response,
+ 0);
+ }
+ else
+ {
+ SIRIPARSER_ASYNC_NEXT_NODE
+ }
+ }
+ }
+}
+
+static void exit_set_timezone(uv_async_t * handle)
+{
+ siridb_query_t * query = (siridb_query_t *) handle->data;
+ cleri_node_t * node = query->nodes->node->children->next->next->node;
+ siridb_t * siridb = query->client->siridb;
+
+ MASTER_CHECK_ACCESSIBLE(siridb)
+
+ char timezone[node->len - 1];
+ strx_extract_string(timezone, node->str, node->len);
+
+ iso8601_tz_t new_tz = iso8601_tz(timezone);
+
+ if (new_tz < 0)
+ {
+ snprintf(query->err_msg,
+ SIRIDB_MAX_SIZE_ERR_MSG,
+ "Unknown time zone: '%s'. (see 'help timezones' "
+ "for a list of valid time zones)",
+ timezone);
+ siridb_query_send_error(handle, CPROTO_ERR_QUERY);
+
+ }
+ else if (siridb->tz == new_tz)
+ {
+ snprintf(query->err_msg,
+ SIRIDB_MAX_SIZE_ERR_MSG,
+ "Database '%s' is already set to time-zone '%s'.",
+ siridb->dbname,
+ timezone);
+ siridb_query_send_error(handle, CPROTO_ERR_QUERY);
+ }
+ else
+ {
+ QP_ADD_SUCCESS
+
+ qp_add_fmt_safe(
+ query->packer,
+ MSG_SUCCES_SET_TIMEZONE,
+ iso8601_tzname(siridb->tz),
+ iso8601_tzname(new_tz));
+
+ siridb->tz = new_tz;
+
+ if (siridb_save(siridb))
+ {
+ log_critical("Could not save database changes (database: '%s')",
+ siridb->dbname);
+ }
+
+ if (IS_MASTER)
+ {
+ siridb_query_forward(
+ handle,
+ SIRIDB_QUERY_FWD_UPDATE,
+ (sirinet_promises_cb) on_update_xxx_response,
+ 0);
+ }
+ else
+ {
+ SIRIPARSER_ASYNC_NEXT_NODE
+ }
+ }
+}
+
+static void exit_show_stmt(uv_async_t * handle)
+{
+ siridb_query_t * query = (siridb_query_t *) handle->data;
+ siridb_t * siridb = query->client->siridb;
+ siridb_user_t * db_user = query->client->origin;
+ SIRIPARSER_MASTER_CHECK_ACCESS(db_user, SIRIDB_ACCESS_SHOW)
+
+ cleri_children_t * children =
+ query->nodes->node->children->next->node->children;
+ siridb_props_cb prop_cb;
+
+#if DEBUG
+ assert (query->packer == NULL);
+#endif
+
+ query->packer = sirinet_packer_new(4096);
+
+ if (query->packer == NULL)
+ {
+ MEM_ERR_RET
+ }
+
+ qp_add_type(query->packer, QP_MAP_OPEN);
+ qp_add_raw(query->packer, (const unsigned char *) "data", 4);
+ qp_add_type(query->packer, QP_ARRAY_OPEN);
+
+ /* set props.h (who_am_i) to current db_name */
+ who_am_i = db_user->name;
+
+ if (children->node == NULL)
+ {
+ /* show all properties */
+ int i;
+
+ for (i = 0; i < KW_COUNT; i++)
+ {
+ if ((prop_cb = siridb_props[i]) == NULL)
+ {
+ continue;
+ }
+ prop_cb(siridb, query->packer, 1);
+ }
+ }
+ else
+ {
+ /* show selected properties chosen by query */
+ while (1)
+ {
+ /* get the callback */
+ prop_cb = siridb_props[children->node->children->node->
+ cl_obj->gid - KW_OFFSET];
+#if DEBUG
+ assert (prop_cb != NULL); /* all props are implemented */
+#endif
+ prop_cb(siridb, query->packer, 1);
+
+ if (children->next == NULL)
+ {
+ break;
+ }
+
+ /* skip one which is the delimiter */
+ children = children->next->next;
+ }
+ }
+
+ qp_add_type(query->packer, QP_ARRAY_CLOSE);
+
+ SIRIPARSER_ASYNC_NEXT_NODE
+}
+
+static void exit_timeit_stmt(uv_async_t * handle)
+{
+ siridb_query_t * query = (siridb_query_t *) handle->data;
+ siridb_t * siridb = query->client->siridb;
+
+ struct timespec end;
+ char * name = siridb->server->name;
+ clock_gettime(CLOCK_REALTIME, &end);
+
+ qp_add_type(query->timeit, QP_MAP2);
+ qp_add_raw(query->timeit, (const unsigned char *) "server", 6);
+ qp_add_string(query->timeit, name);
+ qp_add_raw(query->timeit, (const unsigned char *) "time", 4);
+ qp_add_double(query->timeit,
+ (double) (end.tv_sec - query->start.tv_sec) +
+ (double) (end.tv_nsec - query->start.tv_nsec) / 1000000000.0f);
+
+ if (query->packer == NULL)
+ {
+ /* lets give the new packer the exact size so we do not
+ * need a realloc */
+ query->packer = sirinet_packer_new(
+ query->timeit->len +
+ 1 +
+ sizeof(sirinet_pkg_t));
+
+ if (query->packer == NULL)
+ {
+ MEM_ERR_RET
+ }
+
+ qp_add_type(query->packer, QP_MAP_OPEN);
+ }
+
+ /* extend packer with timeit information */
+ qp_packer_extend(query->packer, query->timeit);
+
+ SIRIPARSER_ASYNC_NEXT_NODE
+}
+
+/******************************************************************************
+ * Async loop functions.
+ *****************************************************************************/
+
+static void async_count_series(uv_async_t * handle)
+{
+ siridb_query_t * query = (siridb_query_t *) handle->data;
+ siridb_series_t * series;
+ query_count_t * q_count = (query_count_t *) query->data;
+ uint8_t async_more = 0;
+
+ size_t index_end = q_count->slist_index + MAX_ITERATE_COUNT;
+
+ if (index_end >= q_count->slist->len)
+ {
+ index_end = q_count->slist->len;
+ }
+ else
+ {
+ async_more = 1;
+ }
+
+ for (; q_count->slist_index < index_end; q_count->slist_index++)
+ {
+ series = (siridb_series_t *) q_count->slist->data[q_count->slist_index];
+ q_count->n += cexpr_run(
+ q_count->where_expr,
+ (cexpr_cb_t) siridb_series_cexpr_cb,
+ series);
+ siridb_series_decref(series);
+ }
+
+ if (async_more)
+ {
+ uv_async_send(handle);
+ }
+ else if (IS_MASTER)
+ {
+ siridb_query_forward(
+ handle,
+ SIRIDB_QUERY_FWD_POOLS,
+ (sirinet_promises_cb) on_count_xxx_response,
+ 0);
+ }
+ else
+ {
+ qp_add_int64(query->packer, q_count->n);
+
+ SIRIPARSER_ASYNC_NEXT_NODE
+ }
+}
+
+static void async_count_series_length(uv_async_t * handle)
+{
+ siridb_query_t * query = (siridb_query_t *) handle->data;
+ siridb_series_t * series;
+ query_count_t * q_count = (query_count_t *) query->data;
+ uint8_t async_more = 0;
+
+ size_t index_end = q_count->slist_index + MAX_ITERATE_COUNT;
+
+ if (index_end >= q_count->slist->len)
+ {
+ index_end = q_count->slist->len;
+ }
+ else
+ {
+ async_more = 1;
+ }
+
+ for (; q_count->slist_index < index_end; q_count->slist_index++)
+ {
+ series = (siridb_series_t *) q_count->slist->data[q_count->slist_index];
+
+ if (cexpr_run(
+ q_count->where_expr,
+ (cexpr_cb_t) siridb_series_cexpr_cb,
+ series))
+ {
+ q_count->n += series->length;
+ }
+
+ siridb_series_decref(series);
+ }
+
+ if (async_more)
+ {
+ uv_async_send(handle);
+ }
+ else if (IS_MASTER)
+ {
+ siridb_query_forward(
+ handle,
+ SIRIDB_QUERY_FWD_POOLS,
+ (sirinet_promises_cb) on_count_xxx_response,
+ 0);
+ }
+ else
+ {
+ qp_add_int64(query->packer, q_count->n);
+
+ SIRIPARSER_ASYNC_NEXT_NODE
+ }
+}
+
+static void async_drop_series(uv_async_t * handle)
+{
+ siridb_query_t * query = (siridb_query_t *) handle->data;
+ query_drop_t * q_drop = (query_drop_t *) query->data;
+ siridb_t * siridb = query->client->siridb;
+
+ siridb_series_t * series;
+ uint8_t async_more = 0;
+
+ size_t index_end = q_drop->slist_index + MAX_ITERATE_COUNT;
+
+ if (index_end >= q_drop->slist->len)
+ {
+ index_end = q_drop->slist->len;
+ }
+ else
+ {
+ async_more = 1;
+ }
+
+ uv_mutex_lock(&siridb->series_mutex);
+
+ for (; q_drop->slist_index < index_end; q_drop->slist_index++)
+ {
+ series = (siridb_series_t *) q_drop->slist->data[q_drop->slist_index];
+ siridb_series_drop(siridb, series);
+ siridb_series_decref(series);
+ }
+
+ uv_mutex_unlock(&siridb->series_mutex);
+
+ /* flush dropped file change to disk */
+ if (q_drop->slist->len)
+ {
+ siridb_series_flush_dropped(siridb);
+ }
+
+ if (async_more)
+ {
+ uv_async_send(handle);
+ }
+ else if (IS_MASTER)
+ {
+ siridb_query_forward(
+ handle,
+ SIRIDB_QUERY_FWD_UPDATE,
+ (sirinet_promises_cb) on_drop_series_response,
+ 0);
+ }
+ else
+ {
+ qp_add_int64(query->packer, q_drop->n);
+
+ SIRIPARSER_ASYNC_NEXT_NODE
+ }
+}
+
+static void async_drop_shards(uv_async_t * handle)
+{
+ siridb_query_t * query = (siridb_query_t *) handle->data;
+ query_drop_t * q_drop = (query_drop_t *) query->data;
+ siridb_t * siridb = query->client->siridb;
+
+ if (q_drop->shards_list->len)
+ {
+ siridb_shard_t * shard = (siridb_shard_t *) slist_pop(
+ q_drop->shards_list);
+
+ siridb_shard_drop(
+ shard,
+ siridb);
+ siridb_shard_decref(shard);
+ }
+
+ if (q_drop->shards_list->len)
+ {
+ uv_async_send(handle);
+ }
+ else if (IS_MASTER)
+ {
+ siridb_query_forward(
+ handle,
+ SIRIDB_QUERY_FWD_UPDATE,
+ (sirinet_promises_cb) on_drop_shards_response,
+ 0);
+ }
+ else
+ {
+ qp_add_int64(query->packer, q_drop->n);
+ SIRIPARSER_ASYNC_NEXT_NODE
+ }
+}
+
+static void async_filter_series(uv_async_t * handle)
+{
+ siridb_query_t * query = (siridb_query_t *) handle->data;
+ query_wrapper_t * q_wrapper = (query_wrapper_t *) query->data;
+ cexpr_t * where_expr = q_wrapper->where_expr;
+ uint8_t async_more = 0;
+ siridb_series_t * series;
+ size_t index_end = q_wrapper->slist_index + MAX_ITERATE_COUNT;
+
+ if (index_end >= q_wrapper->slist->len)
+ {
+ index_end = q_wrapper->slist->len;
+ }
+ else
+ {
+ async_more = 1;
+ }
+
+ for (; q_wrapper->slist_index < index_end; q_wrapper->slist_index++)
+ {
+ series = (siridb_series_t *)
+ q_wrapper->slist->data[q_wrapper->slist_index];
+
+ if (cexpr_run(
+ where_expr,
+ (cexpr_cb_t) siridb_series_cexpr_cb,
+ series))
+ {
+ if (imap_add(q_wrapper->series_map, series->id, series))
+ {
+ log_critical("Cannot add filtered series to internal map.");
+ siridb_series_decref(series);
+ }
+ }
+ else
+ {
+ siridb_series_decref(series);
+ }
+ }
+
+ if (async_more)
+ {
+ uv_async_send(handle);
+ }
+ else
+ {
+ /* free the s-list object and reset index */
+ slist_free(q_wrapper->slist);
+
+ q_wrapper->slist = NULL;
+ q_wrapper->slist_index = 0;
+
+ /* cleanup where statement since we do not need it anymore */
+ cexpr_free(q_wrapper->where_expr);
+ q_wrapper->where_expr = NULL;
+
+ /* we now processed the where statement, continue... */
+ switch (q_wrapper->tp)
+ {
+ case QUERIES_DROP:
+ exit_drop_series(handle);
+ break;
+ case QUERIES_SELECT:
+ exit_select_aggregate(handle);
+ break;
+ default:
+ assert (0);
+ break;
+ }
+ }
+}
+
+static void async_list_series(uv_async_t * handle)
+{
+ siridb_query_t * query = (siridb_query_t *) handle->data;
+ query_list_t * q_list = (query_list_t *) query->data;
+ slist_t * props = q_list->props;
+ cexpr_t * where_expr = q_list->where_expr;
+ uint8_t async_more = 0;
+ siridb_series_t * series;
+ size_t i;
+ size_t index_end = q_list->slist_index + MAX_ITERATE_COUNT;
+
+ if (index_end >= q_list->slist->len)
+ {
+ index_end = q_list->slist->len;
+ }
+ else
+ {
+ async_more = 1;
+ }
+
+ for (; q_list->limit && q_list->slist_index < index_end;
+ q_list->slist_index++)
+ {
+ series = (siridb_series_t *) q_list->slist->data[q_list->slist_index];
+
+ if (where_expr == NULL || cexpr_run(
+ where_expr,
+ (cexpr_cb_t) siridb_series_cexpr_cb,
+ series))
+ {
+ if (!--q_list->limit)
+ {
+ async_more = 0;
+ }
+
+ qp_add_type(query->packer, QP_ARRAY_OPEN);
+
+ for (i = 0; i < props->len; i++)
+ {
+ switch(*((uint32_t *) props->data[i]))
+ {
+ case CLERI_GID_K_NAME:
+ qp_add_raw(
+ query->packer,
+ (const unsigned char *) series->name,
+ series->name_len);
+ break;
+ case CLERI_GID_K_LENGTH:
+ qp_add_int32(query->packer, series->length);
+ break;
+ case CLERI_GID_K_TYPE:
+ qp_add_string(query->packer, series_type_map[series->tp]);
+ break;
+ case CLERI_GID_K_POOL:
+ qp_add_int16(query->packer, series->pool);
+ break;
+ case CLERI_GID_K_START:
+ qp_add_int64(query->packer, series->start);
+ break;
+ case CLERI_GID_K_END:
+ qp_add_int64(query->packer, series->end);
+ break;
+ }
+ }
+
+ qp_add_type(query->packer, QP_ARRAY_CLOSE);
+ }
+
+ siridb_series_decref(series);
+ }
+
+ if (async_more)
+ {
+ uv_async_send(handle);
+ }
+ else if (IS_MASTER && q_list->limit)
+ {
+ /* we have not reached the limit, send the query to other pools */
+ siridb_query_forward(
+ handle,
+ SIRIDB_QUERY_FWD_POOLS,
+ (sirinet_promises_cb) on_list_xxx_response,
+ 0);
+ }
+ else
+ {
+ qp_add_type(query->packer, QP_ARRAY_CLOSE);
+
+ SIRIPARSER_ASYNC_NEXT_NODE
+ }
+}
+
+static void async_no_points_aggregate(uv_async_t * handle)
+{
+ siridb_query_t * query = (siridb_query_t *) handle->data;
+ query_select_t * q_select = (query_select_t *) query->data;
+ siridb_t * siridb = query->client->siridb;
+ uint8_t async_more = 0;
+ siridb_series_t * series;
+ siridb_points_t * points;
+ siridb_points_t * aggr_points;
+ int required_shard = 0;
+
+ for (; q_select->slist_index < q_select->slist->len;
+ ++q_select->slist_index)
+ {
+ if (required_shard > MAX_BATCH_REQUIRE_SHARD)
+ {
+ async_more = 1;
+ break;
+ }
+
+ series = (siridb_series_t *)
+ q_select->slist->data[q_select->slist_index];
+ /*
+ * We must decrement the ref count immediately since the index is
+ * incremented by one. The series will not be freed since at least
+ * 'series_map' still has a reference.
+ */
+ siridb_series_decref(series);
+
+#if DEBUG
+ assert (q_select->alist->len >= 1);
+#endif
+
+ siridb_aggr_t * aggr = q_select->alist->data[0];
+
+ uv_mutex_lock(&siridb->series_mutex);
+
+ switch (aggr->gid)
+ {
+ case CLERI_GID_F_COUNT:
+ points = siridb_series_get_count(series);
+ break;
+ case CLERI_GID_F_FIRST:
+ points = siridb_series_get_first(series, &required_shard);
+ break;
+ case CLERI_GID_F_LAST:
+ points = siridb_series_get_last(series, &required_shard);
+ break;
+ default:
+ assert (0);
+ }
+
+ uv_mutex_unlock(&siridb->series_mutex);
+
+ if (points != NULL)
+ {
+ const char * name;
+ size_t i;
+
+ for (i = 1; points->len && i < q_select->alist->len; i++)
+ {
+ aggr_points = siridb_aggregate_run(
+ points,
+ (siridb_aggr_t *) q_select->alist->data[i],
+ query->err_msg);
+
+ if (aggr_points != points)
+ {
+ siridb_points_free(points);
+ }
+
+ if (aggr_points == NULL)
+ {
+ siridb_query_send_error(handle, CPROTO_ERR_QUERY);
+ return;
+ }
+
+ points = aggr_points;
+ }
+
+ q_select->n += points->len;
+
+ if (q_select->merge_as == NULL)
+ {
+ name = siridb_presuf_name(
+ q_select->presuf,
+ series->name,
+ series->name_len);
+
+ if (name == NULL || ct_add(q_select->result, name, points))
+ {
+ sprintf(query->err_msg, "Error adding points to map.");
+ siridb_points_free(points);
+ log_critical("Critical error adding points");
+ siridb_query_send_error(handle, CPROTO_ERR_QUERY);
+ return;
+ }
+ }
+ else
+ {
+ slist_t ** plist;
+
+ name = siridb_presuf_name(
+ q_select->presuf,
+ q_select->merge_as,
+ strlen(q_select->merge_as));
+
+ plist = (slist_t **) ct_getaddr(q_select->result, name);
+
+ if ( name == NULL ||
+ plist == NULL ||
+ slist_append_safe(plist, points))
+ {
+ sprintf(query->err_msg, "Error adding points to map.");
+ siridb_points_free(points);
+ log_critical("Critical error adding points");
+ siridb_query_send_error(handle, CPROTO_ERR_QUERY);
+ return;
+ }
+ }
+ }
+ }
+
+ if (async_more)
+ {
+ uv_async_send(handle);
+ }
+ else
+ {
+ siridb_aggregate_list_free(q_select->alist);
+ q_select->alist = NULL;
+
+ slist_free(q_select->slist);
+ q_select->slist = NULL;
+ q_select->slist_index = 0;
+
+ SIRIPARSER_ASYNC_NEXT_NODE
+ }
+}
+
+static void async_select_aggregate(uv_async_t * handle)
+{
+ siridb_query_t * query = (siridb_query_t *) handle->data;
+ query_select_t * q_select = (query_select_t *) query->data;
+ siridb_t * siridb = query->client->siridb;
+ uint8_t async_more = 0;
+ siridb_series_t * series;
+ siridb_points_t * points;
+ siridb_points_t * aggr_points;
+
+ if (q_select->n > siridb->select_points_limit)
+ {
+ snprintf(query->err_msg,
+ SIRIDB_MAX_SIZE_ERR_MSG,
+ "Query has reached the maximum number of selected points "
+ "(%u). Please use another time window, an aggregation "
+ "function or select less series to reduce the number of "
+ "points.",
+ siridb->select_points_limit);
+
+ siridb_query_send_error(handle, CPROTO_ERR_QUERY);
+ return;
+ }
+
+ series = (siridb_series_t *)
+ q_select->slist->data[q_select->slist_index];
+
+ /*
+ * We must decrement the ref count immediately since we now update the
+ * index by one. The series will not be freed since at least 'series_map'
+ * still has a reference.
+ */
+ siridb_series_decref(series);
+
+ if ((++q_select->slist_index) < q_select->slist->len)
+ {
+ async_more = 1;
+ }
+
+ /* We try to read the points from the cache in case a cache is created.
+ * If there are more select functions left we create a copy of the cache.
+ * When this is the last select function we pop from the cache since the
+ * points are no longer required.
+ */
+ points = (q_select->points_map == NULL) ?
+ NULL :
+ q_select->nselects ?
+ siridb_points_copy(imap_get(q_select->points_map, series->id)):
+ imap_pop(q_select->points_map, series->id);
+
+ if (points == NULL)
+ {
+ uv_mutex_lock(&siridb->series_mutex);
+
+ points = (series->flags & SIRIDB_SERIES_IS_DROPPED) ?
+ NULL : siridb_series_get_points(
+ series,
+ q_select->start_ts,
+ q_select->end_ts);
+ uv_mutex_unlock(&siridb->series_mutex);
+
+ /* when having a cache and points, add a copy of points to the cache */
+ if (q_select->points_map != NULL && points != NULL)
+ {
+ siridb_points_t * cpoints = siridb_points_copy(points);
+ if (cpoints != NULL &&
+ imap_add(q_select->points_map, series->id, cpoints))
+ {
+ siridb_points_free(cpoints);
+ }
+ }
+ }
+
+ if (points != NULL)
+ {
+ const char * name;
+ size_t i;
+
+ for (i = 0; points->len && i < q_select->alist->len; i++)
+ {
+ aggr_points = siridb_aggregate_run(
+ points,
+ (siridb_aggr_t *) q_select->alist->data[i],
+ query->err_msg);
+
+ if (aggr_points != points)
+ {
+ siridb_points_free(points);
+ }
+
+ if (aggr_points == NULL)
+ {
+ siridb_query_send_error(handle, CPROTO_ERR_QUERY);
+ return;
+ }
+
+ points = aggr_points;
+ }
+
+ q_select->n += points->len;
+
+ if (q_select->merge_as == NULL)
+ {
+ name = siridb_presuf_name(
+ q_select->presuf,
+ series->name,
+ series->name_len);
+
+ if (name == NULL || ct_add(q_select->result, name, points))
+ {
+ sprintf(query->err_msg, "Error adding points to map.");
+ siridb_points_free(points);
+ log_critical("Critical error adding points");
+ siridb_query_send_error(handle, CPROTO_ERR_QUERY);
+ return;
+ }
+ }
+ else
+ {
+ slist_t ** plist;
+
+ name = siridb_presuf_name(
+ q_select->presuf,
+ q_select->merge_as,
+ strlen(q_select->merge_as));
+
+ plist = (slist_t **) ct_getaddr(q_select->result, name);
+
+ if ( name == NULL ||
+ plist == NULL ||
+ slist_append_safe(plist, points))
+ {
+ sprintf(query->err_msg, "Error adding points to map.");
+ siridb_points_free(points);
+ log_critical("Critical error adding points");
+ siridb_query_send_error(handle, CPROTO_ERR_QUERY);
+ return;
+ }
+ }
+ }
+
+ if (async_more)
+ {
+ uv_async_send(handle);
+ }
+ else
+ {
+ siridb_aggregate_list_free(q_select->alist);
+ q_select->alist = NULL;
+
+ slist_free(q_select->slist);
+ q_select->slist = NULL;
+ q_select->slist_index = 0;
+
+ SIRIPARSER_ASYNC_NEXT_NODE
+ }
+}
+
+static void async_series_re(uv_async_t * handle)
+{
+ siridb_query_t * query = (siridb_query_t *) handle->data;
+ query_wrapper_t * q_wrapper = (query_wrapper_t *) query->data;
+ uint8_t async_more = 0;
+ siridb_series_t * series;
+ size_t index_end = q_wrapper->slist_index + MAX_ITERATE_COUNT;
+
+ if (index_end >= q_wrapper->slist->len)
+ {
+ index_end = q_wrapper->slist->len;
+ }
+ else
+ {
+ async_more = 1;
+ }
+
+ int pcre_exec_ret;
+
+ for (; q_wrapper->slist_index < index_end; q_wrapper->slist_index++)
+ {
+ series = (siridb_series_t *)
+ q_wrapper->slist->data[q_wrapper->slist_index];
+
+ pcre_exec_ret = pcre2_match(
+ q_wrapper->regex,
+ (PCRE2_SPTR8) series->name,
+ series->name_len,
+ 0, /* start looking at this point */
+ 0, /* OPTIONS */
+ q_wrapper->match_data,
+ 0); /* length of sub_str_vec */
+ if ( pcre_exec_ret < 0 ||
+ imap_add(q_wrapper->series_tmp, series->id, series))
+ {
+ siridb_series_decref(series);
+ }
+ }
+
+ if (async_more)
+ {
+ uv_async_send(handle);
+ }
+ else
+ {
+ /* free the s-list object and reset index */
+ slist_free(q_wrapper->slist);
+
+ pcre2_code_free(q_wrapper->regex);
+ pcre2_match_data_free(q_wrapper->match_data);
+
+ q_wrapper->regex = NULL;
+ q_wrapper->match_data = NULL;
+
+ q_wrapper->slist = NULL;
+ q_wrapper->slist_index = 0;
+
+ if (q_wrapper->update_cb != NULL)
+ {
+ (*q_wrapper->update_cb)(
+ q_wrapper->series_map,
+ q_wrapper->series_tmp,
+ (imap_free_cb) &siridb__series_decref);
+ }
+ q_wrapper->series_tmp = NULL;
+
+ SIRIPARSER_ASYNC_NEXT_NODE
+ }
+}
+
+/******************************************************************************
+ * On Response functions
+ *****************************************************************************/
+
+/*
+ * Call-back function: sirinet_promise_cb
+ */
+static void on_ack_response(
+ sirinet_promise_t * promise,
+ sirinet_pkg_t * pkg,
+ int status)
+{
+ uv_async_t * handle = (uv_async_t *) promise->data;
+
+ /* decrement the handle reference counter */
+ siri_async_decref(&handle);
+
+ if (handle != NULL)
+ {
+ siridb_query_t * query = (siridb_query_t *) handle->data;
+
+ if (status == PROMISE_SUCCESS)
+ {
+ switch (pkg->tp)
+ {
+ case BPROTO_ACK_LOG_LEVEL:
+ /* success message is already set */
+ break;
+ case BPROTO_ACK_ENABLE_BACKUP_MODE:
+ /* success message is already set */
+ break;
+ case BPROTO_ACK_DISABLE_BACKUP_MODE:
+ /* success message is already set */
+ break;
+
+ default:
+ status = PROMISE_PKG_TYPE_ERROR;
+ break;
+ }
+ }
+
+ if (status)
+ {
+ snprintf(query->err_msg,
+ SIRIDB_MAX_SIZE_ERR_MSG,
+ "Error occurred while sending the request to '%s' (%s)",
+ promise->server->name,
+ sirinet_promise_strstatus(status));
+ siridb_query_send_error(handle, CPROTO_ERR_QUERY);
+ }
+ else
+ {
+ SIRIPARSER_ASYNC_NEXT_NODE
+ }
+ }
+
+ /* we must free the promise */
+ sirinet_promise_decref(promise);
+}
+
+/*
+ * Call-back function: sirinet_promises_cb
+ *
+ * Make sure to run siri_async_incref() on the handle
+ */
+static void on_alter_xxx_response(slist_t * promises, uv_async_t * handle)
+{
+ ON_PROMISES
+
+ siridb_query_t * query = (siridb_query_t *) handle->data;
+ sirinet_pkg_t * pkg;
+ sirinet_promise_t * promise;
+ qp_unpacker_t unpacker;
+ qp_obj_t qp_count;
+ query_alter_t * q_alter = (query_alter_t *) query->data;
+ size_t i;
+
+ for (i = 0; i < promises->len; i++)
+ {
+ promise = promises->data[i];
+
+ if (promise == NULL)
+ {
+ continue;
+ }
+
+ pkg = (sirinet_pkg_t *) promise->data;
+
+ if (pkg != NULL && pkg->tp == BPROTO_RES_QUERY)
+ {
+ qp_unpacker_init(&unpacker, pkg->data, pkg->len);
+
+ if ( qp_is_map(qp_next(&unpacker, NULL)) &&
+ qp_is_raw(qp_next(&unpacker, NULL)) && /* servers etc.*/
+ qp_is_int(qp_next(&unpacker, &qp_count))) /* one result*/
+ {
+ q_alter->n += qp_count.via.int64;
+
+ /* extract time-it info if needed */
+ if (query->timeit != NULL)
+ {
+ siridb_query_timeit_from_unpacker(query, &unpacker);
+ }
+ }
+ }
+
+ /* make sure we free the promise and data */
+ free(promise->data);
+ sirinet_promise_decref(promise);
+ }
+ /*
+ * Note: since this function has the sole purpose for alter servers
+ * and setting log levels, we now simply ad the message here.
+ */
+ QP_ADD_SUCCESS
+
+ log_info(MSG_SUCCES_SET_LOG_LEVEL_MULTI,
+ logger_level_name(q_alter->n >> 16),
+ q_alter->n & 0xffff);
+
+ qp_add_fmt_safe(
+ query->packer,
+ MSG_SUCCES_SET_LOG_LEVEL_MULTI,
+ logger_level_name(q_alter->n >> 16),
+ q_alter->n & 0xffff);
+
+ SIRIPARSER_ASYNC_NEXT_NODE
+}
+
+/*
+ * Call-back function: sirinet_promises_cb
+ *
+ * Make sure to run siri_async_incref() on the handle
+ */
+static void on_count_xxx_response(slist_t * promises, uv_async_t * handle)
+{
+ ON_PROMISES
+
+ uint8_t error_tp = 0;
+ siridb_query_t * query = (siridb_query_t *) handle->data;
+ sirinet_pkg_t * pkg;
+ sirinet_promise_t * promise;
+ qp_unpacker_t unpacker;
+ qp_obj_t qp_count;
+ query_count_t * q_count = (query_count_t *) query->data;
+ size_t i;
+
+ for (i = 0; i < promises->len; i++)
+ {
+ promise = promises->data[i];
+
+ if (promise == NULL)
+ {
+ continue;
+ }
+
+ pkg = (sirinet_pkg_t *) promise->data;
+
+ if (pkg != NULL && pkg->tp == BPROTO_RES_QUERY)
+ {
+ qp_unpacker_init(&unpacker, pkg->data, pkg->len);
+
+ if ( qp_is_map(qp_next(&unpacker, NULL)) &&
+ qp_is_raw(qp_next(&unpacker, NULL)) && /* servers etc.*/
+ qp_is_int(qp_next(&unpacker, &qp_count))) /* one result*/
+ {
+ q_count->n += qp_count.via.int64;
+
+ /* extract time-it info if needed */
+ if (query->timeit != NULL)
+ {
+ siridb_query_timeit_from_unpacker(query, &unpacker);
+ }
+ }
+ }
+ else if (pkg != NULL &&
+ !error_tp &&
+ sirinet_protocol_is_error_msg(pkg->tp) &&
+ siridb_query_err_from_pkg(query, pkg) == 0)
+ {
+ error_tp = pkg->tp;
+ }
+
+ /* make sure we free the promise and data */
+ free(promise->data);
+ sirinet_promise_decref(promise);
+ }
+
+ if (error_tp)
+ {
+ siridb_query_send_error(handle, error_tp);
+ }
+ else
+ {
+ qp_add_int64(query->packer, q_count->n);
+
+ SIRIPARSER_ASYNC_NEXT_NODE
+ }
+}
+
+/*
+ * Call-back function: sirinet_promises_cb
+ *
+ * Make sure to run siri_async_incref() on the handle
+ */
+static void on_drop_series_response(slist_t * promises, uv_async_t * handle)
+{
+ ON_PROMISES
+
+ siridb_query_t * query = (siridb_query_t *) handle->data;
+ sirinet_pkg_t * pkg;
+ sirinet_promise_t * promise;
+ qp_unpacker_t unpacker;
+ qp_obj_t qp_drop;
+ query_drop_t * q_drop = (query_drop_t *) query->data;
+ size_t i;
+
+ for (i = 0; i < promises->len; i++)
+ {
+ promise = promises->data[i];
+
+ if (promise == NULL)
+ {
+ continue;
+ }
+
+ pkg = (sirinet_pkg_t *) promise->data;
+
+ if (pkg != NULL && pkg->tp == BPROTO_RES_QUERY)
+ {
+ qp_unpacker_init(&unpacker, pkg->data, pkg->len);
+
+ if ( qp_is_map(qp_next(&unpacker, NULL)) &&
+ qp_is_raw(qp_next(&unpacker, NULL)) && /* servers etc.*/
+ qp_is_int(qp_next(&unpacker, &qp_drop))) /* one result */
+ {
+ q_drop->n += qp_drop.via.int64;
+
+ /* extract time-it info if needed */
+ if (query->timeit != NULL)
+ {
+ siridb_query_timeit_from_unpacker(query, &unpacker);
+ }
+ }
+ }
+
+ /* make sure we free the promise and data */
+ free(promise->data);
+ sirinet_promise_decref(promise);
+ }
+
+ qp_add_fmt(query->packer, MSG_SUCCES_DROP_SERIES, q_drop->n);
+
+ SIRIPARSER_ASYNC_NEXT_NODE
+}
+
+/*
+ * Call-back function: sirinet_promises_cb
+ *
+ * Make sure to run siri_async_incref() on the handle
+ */
+static void on_drop_shards_response(slist_t * promises, uv_async_t * handle)
+{
+ ON_PROMISES
+
+ siridb_query_t * query = (siridb_query_t *) handle->data;
+ sirinet_pkg_t * pkg;
+ sirinet_promise_t * promise;
+ qp_unpacker_t unpacker;
+ qp_obj_t qp_drop;
+ query_drop_t * q_drop = (query_drop_t *) query->data;
+ size_t i;
+
+ for (i = 0; i < promises->len; i++)
+ {
+ promise = promises->data[i];
+
+ if (promise == NULL)
+ {
+ continue;
+ }
+
+ pkg = (sirinet_pkg_t *) promise->data;
+
+ if (pkg != NULL && pkg->tp == BPROTO_RES_QUERY)
+ {
+ qp_unpacker_init(&unpacker, pkg->data, pkg->len);
+
+ if ( qp_is_map(qp_next(&unpacker, NULL)) &&
+ qp_is_raw(qp_next(&unpacker, NULL)) && /* shards */
+ qp_is_int(qp_next(&unpacker, &qp_drop))) /* one result */
+ {
+ q_drop->n += qp_drop.via.int64;
+
+ /* extract time-it info if needed */
+ if (query->timeit != NULL)
+ {
+ siridb_query_timeit_from_unpacker(query, &unpacker);
+ }
+ }
+ }
+
+ /* make sure we free the promise and data */
+ free(promise->data);
+ sirinet_promise_decref(promise);
+ }
+
+ qp_add_fmt(query->packer, MSG_SUCCES_DROP_SHARDS, q_drop->n);
+
+ SIRIPARSER_ASYNC_NEXT_NODE
+}
+
+/*
+ * Call-back function: sirinet_promises_cb
+ *
+ * Make sure to run siri_async_incref() on the handle
+ */
+static void on_groups_response(slist_t * promises, uv_async_t * handle)
+{
+ ON_PROMISES
+
+ sirinet_pkg_t * pkg;
+ sirinet_promise_t * promise;
+ qp_unpacker_t unpacker;
+ siridb_query_t * query = (siridb_query_t *) handle->data;
+ siridb_t * siridb = query->client->siridb;
+ siridb_group_t * group;
+ qp_obj_t qp_name;
+ qp_obj_t qp_series;
+ size_t i;
+
+ siridb_groups_init_nseries(siridb->groups);
+
+ for (i = 0; i < promises->len; i++)
+ {
+ promise = promises->data[i];
+
+ if (promise == NULL)
+ {
+ continue;
+ }
+
+ pkg = (sirinet_pkg_t *) promise->data;
+
+ if (pkg != NULL && pkg->tp == BPROTO_RES_GROUPS)
+ {
+ qp_unpacker_init(&unpacker, pkg->data, pkg->len);
+
+ if ( qp_is_array(qp_next(&unpacker, NULL)))
+ {
+ while ( qp_is_array(qp_next(&unpacker, NULL)) &&
+ qp_is_raw(qp_next(&unpacker, &qp_name)) &&
+ qp_is_raw_term(&qp_name) &&
+ qp_is_int(qp_next(&unpacker, &qp_series)))
+ {
+ group = (siridb_group_t *) ct_get(
+ siridb->groups->groups,
+ (const char *) qp_name.via.raw);
+ if (group != NULL)
+ {
+ group->n += qp_series.via.int64;
+ }
+ }
+ }
+ }
+
+ /* make sure we free the promise and data */
+ free(promise->data);
+ sirinet_promise_decref(promise);
+ }
+
+ query->nodes->cb(handle);
+}
+
+/*
+ * Call-back function: sirinet_promises_cb
+ *
+ * Make sure to run siri_async_incref() on the handle
+ */
+static void on_list_xxx_response(slist_t * promises, uv_async_t * handle)
+{
+ ON_PROMISES
+
+ int error_tp = 0;
+ sirinet_pkg_t * pkg;
+ sirinet_promise_t * promise;
+ qp_unpacker_t unpacker;
+ siridb_query_t * query = (siridb_query_t *) handle->data;
+ query_list_t * q_list = (query_list_t *) query->data;
+ size_t i;
+
+ for (i = 0; i < promises->len; i++)
+ {
+ promise = promises->data[i];
+
+ if (promise == NULL)
+ {
+ continue;
+ }
+
+ pkg = (sirinet_pkg_t *) promise->data;
+
+ if (pkg != NULL && pkg->tp == BPROTO_RES_QUERY)
+ {
+ qp_unpacker_init(&unpacker, pkg->data, pkg->len);
+
+ if ( qp_is_map(qp_next(&unpacker, NULL)) &&
+ qp_is_raw(qp_next(&unpacker, NULL)) && /* columns */
+ qp_is_array(qp_skip_next(&unpacker)) &&
+ qp_is_raw(qp_next(&unpacker, NULL)) && /* series/... */
+ qp_is_array(qp_next(&unpacker, NULL))) /* results */
+ {
+ while (qp_is_array(qp_current(&unpacker)))
+ {
+ if (q_list->limit)
+ {
+ qp_packer_extend_fu(query->packer, &unpacker);
+ q_list->limit--;
+ }
+ else
+ {
+ qp_skip_next(&unpacker);
+ }
+ }
+
+ /* extract time-it info if needed */
+ if (query->timeit != NULL)
+ {
+ siridb_query_timeit_from_unpacker(query, &unpacker);
+ }
+ }
+ }
+ else if (pkg != NULL &&
+ !error_tp &&
+ sirinet_protocol_is_error_msg(pkg->tp) &&
+ siridb_query_err_from_pkg(query, pkg) == 0)
+ {
+ error_tp = pkg->tp;
+ }
+
+ /* make sure we free the promise and data */
+ free(promise->data);
+ sirinet_promise_decref(promise);
+ }
+
+ if (error_tp)
+ {
+ siridb_query_send_error(handle, error_tp);
+ }
+ else
+ {
+ qp_add_type(query->packer, QP_ARRAY_CLOSE);
+ SIRIPARSER_ASYNC_NEXT_NODE
+ }
+}
+
+/*
+ * Call-back function: sirinet_promises_cb
+ *
+ * Make sure to run siri_async_incref() on the handle
+ */
+static void on_select_response(slist_t * promises, uv_async_t * handle)
+{
+ ON_PROMISES
+
+ sirinet_pkg_t * pkg;
+ sirinet_promise_t * promise;
+ qp_unpacker_t unpacker;
+ siridb_query_t * query = (siridb_query_t *) handle->data;
+ siridb_t * siridb = query->client->siridb;
+ size_t err_count = 0;
+ query_select_t * q_select = (query_select_t *) query->data;
+ qp_obj_t qp_name;
+ qp_obj_t qp_tp;
+ qp_obj_t qp_len;
+ qp_obj_t qp_points;
+ qp_obj_t qp_err_msg;
+ size_t i;
+
+ for (i = 0; i < promises->len; i++)
+ {
+ promise = promises->data[i];
+
+ if (promise == NULL)
+ {
+ err_count++;
+ snprintf(query->err_msg,
+ SIRIDB_MAX_SIZE_ERR_MSG,
+ "Error occurred while sending the select query to at "
+ "least one required server");
+ }
+ else
+ {
+ pkg = (sirinet_pkg_t *) promise->data;
+
+ if (pkg == NULL || pkg->tp != BPROTO_RES_QUERY)
+ {
+ err_count++;
+
+ if (pkg != NULL && pkg->tp == BPROTO_ERR_QUERY)
+ {
+ qp_unpacker_init(&unpacker, pkg->data, pkg->len);
+
+ if ( qp_is_map(qp_next(&unpacker, NULL)) &&
+ qp_is_raw(qp_next(&unpacker, NULL)) &&
+ qp_is_raw(qp_next(&unpacker, &qp_err_msg)))
+ {
+ snprintf(query->err_msg,
+ SIRIDB_MAX_SIZE_ERR_MSG,
+ "%.*s",
+ (int) qp_err_msg.len,
+ qp_err_msg.via.raw);
+ }
+ else
+ {
+ snprintf(query->err_msg,
+ SIRIDB_MAX_SIZE_ERR_MSG,
+ "Error occurred while sending request to "
+ "at least '%s'",
+ promise->server->name);
+ }
+ }
+ else
+ {
+ snprintf(query->err_msg,
+ SIRIDB_MAX_SIZE_ERR_MSG,
+ "Error occurred while sending request to "
+ "at least '%s'",
+ promise->server->name);
+ }
+ }
+ else
+ {
+ qp_unpacker_init(&unpacker, pkg->data, pkg->len);
+
+ if ( qp_is_map(qp_next(&unpacker, NULL)) &&
+ qp_is_raw(qp_next(&unpacker, NULL)) && /* select */
+ qp_is_map(qp_next(&unpacker, NULL)))
+ {
+ if (q_select->merge_as == NULL)
+ {
+ on_select_unpack_points(
+ &unpacker,
+ q_select,
+ &qp_name,
+ &qp_tp,
+ &qp_len,
+ &qp_points,
+ siridb->select_points_limit);
+ }
+ else
+ {
+ on_select_unpack_merged_points(
+ &unpacker,
+ q_select,
+ &qp_name,
+ &qp_tp,
+ &qp_len,
+ &qp_points,
+ siridb->select_points_limit);
+ }
+
+
+ /* extract time-it info if needed */
+ if (query->timeit != NULL)
+ {
+ siridb_query_timeit_from_unpacker(query, &unpacker);
+ }
+ }
+ }
+
+ /* make sure we free the promise and data */
+ free(promise->data);
+ sirinet_promise_decref(promise);
+ }
+ }
+
+ if (q_select->n > siridb->select_points_limit)
+ {
+ snprintf(query->err_msg,
+ SIRIDB_MAX_SIZE_ERR_MSG,
+ "Query has reached the maximum number of selected points "
+ "(%u). Please use another time window, an aggregation "
+ "function or select less series to reduce the number of "
+ "points.",
+ siridb->select_points_limit);
+ siridb_query_send_error(handle, CPROTO_ERR_QUERY);
+ }
+ else if (err_count)
+ {
+ siridb_query_send_error(handle, CPROTO_ERR_QUERY);
+ }
+ else
+ {
+ uv_async_t * next;
+ uv_work_t * work = (uv_work_t *) malloc(sizeof(uv_work_t));
+ if (work == NULL)
+ {
+ MEM_ERR_RET
+ }
+
+ next = (uv_async_t *) malloc(sizeof(uv_async_t));
+ if (next == NULL)
+ {
+ free(work);
+ MEM_ERR_RET
+ }
+
+ uv_close((uv_handle_t *) handle, (uv_close_cb) free);
+
+ handle = next;
+ handle->data = query;
+ siridb_nodes_next(&query->nodes);
+
+ uv_async_init(
+ siri.loop,
+ handle,
+ (query->nodes == NULL) ?
+ (uv_async_cb) siridb_send_query_result :
+ (uv_async_cb) query->nodes->cb);
+
+ siri_async_incref(handle);
+ work->data = handle;
+ uv_queue_work(
+ siri.loop,
+ work,
+ &master_select_work,
+ &master_select_work_finish);
+
+ }
+}
+
+/*
+ * Call-back function: sirinet_promises_cb
+ *
+ * Make sure to run siri_async_incref() on the handle
+ */
+static void on_update_xxx_response(slist_t * promises, uv_async_t * handle)
+{
+ ON_PROMISES
+
+ sirinet_pkg_t * pkg;
+ sirinet_promise_t * promise;
+ siridb_query_t * query = (siridb_query_t *) handle->data;
+ size_t err_count = 0;
+ size_t i;
+
+ for (i = 0; i < promises->len; i++)
+ {
+ promise = promises->data[i];
+
+ if (promise == NULL)
+ {
+ err_count++;
+ snprintf(query->err_msg,
+ SIRIDB_MAX_SIZE_ERR_MSG,
+ "Error occurred while sending the database change to at "
+ "least one required server");
+ }
+ else
+ {
+ pkg = (sirinet_pkg_t *) promise->data;
+
+ if (pkg == NULL || pkg->tp != BPROTO_RES_QUERY)
+ {
+ err_count++;
+ snprintf(query->err_msg,
+ SIRIDB_MAX_SIZE_ERR_MSG,
+ "Error occurred while sending the database change to "
+ "at least '%s'", promise->server->name);
+ }
+
+ /* make sure we free the promise and data */
+ free(promise->data);
+ sirinet_promise_decref(promise);
+ }
+ }
+
+ if (err_count)
+ {
+ siridb_query_send_error(handle, CPROTO_ERR_QUERY);
+ }
+ else
+ {
+ SIRIPARSER_ASYNC_NEXT_NODE
+ }
+}
+
+/******************************************************************************
+ * Helper functions
+ *****************************************************************************/
+
+
+static void master_select_work(uv_work_t * work)
+{
+ uv_async_t * handle = (uv_async_t *) work->data;
+ siridb_query_t * query = (siridb_query_t *) handle->data;
+ query_select_t * q_select = (query_select_t *) query->data;
+ siridb_t * siridb = query->client->siridb;
+ siridb->selected_points += q_select->n;
+ int rc = ct_items(
+ q_select->result,
+ (q_select->merge_as == NULL) ?
+ (ct_item_cb) &items_select_master
+ :
+ (ct_item_cb) &items_select_master_merge,
+ handle);
+
+ /* Do not set an error message when rc==1 since in that case the message
+ * is already set.
+ */
+ switch (rc)
+ {
+ case -1:
+ sprintf(query->err_msg, "Memory allocation error.");
+ /* FALLTHRU */
+ /* no break */
+ case 1:
+ query->flags |= SIRIDB_QUERY_FLAG_ERR;
+ }
+}
+
+static void master_select_work_finish(uv_work_t * work, int status)
+{
+ if (status)
+ {
+ log_error("Select work failed (error: %s)", uv_strerror(status));
+ }
+ else if (!siri_err)
+ {
+ /*
+ * We need to check for SiriDB errors because this task is running in
+ * another thread. In case a siri_err is set, this means we are in forced
+ * closing state and we should not use the handle but let siri close it.
+ */
+
+ uv_async_t * handle = (uv_async_t *) work->data;
+ siridb_query_t * query = (siridb_query_t *) handle->data;
+
+ if (query->flags & SIRIDB_QUERY_FLAG_ERR)
+ {
+ siridb_query_send_error(handle, CPROTO_ERR_QUERY);
+ }
+ else
+ {
+ uv_async_send(handle);
+ }
+ }
+
+ siri_async_decref((uv_async_t **) &work->data);
+
+ free(work);
+}
+
+static int items_select_master(
+ const char * name,
+ size_t len,
+ siridb_points_t * points,
+ uv_async_t * handle)
+{
+ siridb_query_t * query = (siridb_query_t *) handle->data;
+
+ if (query->factor)
+ {
+ siridb_points_ts_correction(points, (double) query->factor);
+ }
+
+ if ( qp_add_raw(query->packer, (const unsigned char *) name, len) ||
+ siridb_points_pack(points, query->packer))
+ {
+ sprintf(query->err_msg, "Memory allocation error.");
+ return -1;
+ }
+
+ return 0;
+}
+
+static int items_select_master_merge(
+ const char * name,
+ size_t len,
+ slist_t * plist,
+ uv_async_t * handle)
+{
+ siridb_query_t * query = (siridb_query_t *) handle->data;
+ query_select_t * q_select = (query_select_t *) query->data;
+ siridb_points_t * points;
+
+ if (qp_add_raw(query->packer, (const unsigned char *) name, len))
+ {
+ sprintf(query->err_msg, "Memory allocation error.");
+ return -1;
+ }
+
+ switch (plist->len)
+ {
+ case 0:
+ points = siridb_points_new(0, TP_INT);
+ if (points == NULL)
+ {
+ sprintf(query->err_msg, "Memory allocation error.");
+ }
+ break;
+ case 1:
+ points = slist_pop(plist);
+ break;
+ default:
+ points = siridb_points_merge(plist, query->err_msg);
+ break;
+ }
+
+ if (q_select->mlist != NULL && points != NULL)
+ {
+ siridb_points_t * aggr_points;
+ size_t i;
+
+ for (i = 0; points->len && i < q_select->mlist->len; i++)
+ {
+ aggr_points = siridb_aggregate_run(
+ points,
+ (siridb_aggr_t *) q_select->mlist->data[i],
+ query->err_msg);
+
+ if (aggr_points != points)
+ {
+ siridb_points_free(points);
+ }
+
+ if (aggr_points == NULL)
+ {
+ return -1; /* (error message is set) */
+ }
+
+ points = aggr_points;
+ }
+ }
+
+ if (points == NULL)
+ {
+ /*
+ * The list will be cleared including the points since 'merge_as'
+ * is still not NULL. (error message is set)
+ */
+ return -1;
+ }
+
+ if (query->factor)
+ {
+ siridb_points_ts_correction(points, (double) query->factor);
+ }
+
+ if (siridb_points_pack(points, query->packer))
+ {
+ sprintf(query->err_msg, "Memory allocation error.");
+ siridb_points_free(points);
+ return -1;
+ }
+
+ siridb_points_free(points);
+
+ return 0;
+}
+
+/*
+ * Returns 0 when successful and -1 in case of an error.
+ * (a SIGNAL is raised in case of an error)
+ */
+static int items_select_other(
+ const char * name,
+ size_t len,
+ siridb_points_t * points,
+ uv_async_t * handle)
+{
+ siridb_query_t * query = (siridb_query_t *) handle->data;
+
+ return -(qp_add_raw_term(
+ query->packer, (const unsigned char *) name, len) ||
+ siridb_points_raw_pack(points, query->packer));
+}
+
+/*
+ * Returns 0 when successful and -1 in case of an error.
+ * (a SIGNAL is raised in case of an error)
+ */
+static int items_select_other_merge(
+ const char * name,
+ size_t len,
+ slist_t * plist,
+ uv_async_t * handle)
+{
+ size_t i;
+ siridb_query_t * query = (siridb_query_t *) handle->data;
+ int rc = qp_add_raw_term(
+ query->packer, (const unsigned char *) name, len) ||
+ qp_add_type(query->packer, QP_ARRAY_OPEN);
+
+ for (i = 0; !rc && i < plist->len; i++)
+ {
+ rc = siridb_points_raw_pack(
+ (siridb_points_t * ) plist->data[i],
+ query->packer);
+ }
+
+ return -(rc || qp_add_type(query->packer, QP_ARRAY_CLOSE));
+}
+
+static void on_select_unpack_points(
+ qp_unpacker_t * unpacker,
+ query_select_t * q_select,
+ qp_obj_t * qp_name,
+ qp_obj_t * qp_tp,
+ qp_obj_t * qp_len,
+ qp_obj_t * qp_points,
+ uint32_t select_points_limit)
+{
+ siridb_points_t * points;
+
+ while ( q_select->n <= select_points_limit &&
+ qp_is_raw(qp_next(unpacker, qp_name)) &&
+ qp_is_raw_term(qp_name) &&
+ qp_is_array(qp_next(unpacker, NULL)) &&
+ qp_is_int(qp_next(unpacker, qp_tp)) &&
+ qp_is_int(qp_next(unpacker, qp_len)) &&
+ qp_is_raw(qp_next(unpacker, qp_points)))
+ {
+ points = siridb_points_new(qp_len->via.int64, qp_tp->via.int64);
+ if (points != NULL)
+ {
+ if (points->tp == TP_STRING)
+ {
+ if (qp_len->via.int64 < POINTS_ZIP_THRESHOLD)
+ {
+ siridb_points_unzip_string_raw(
+ points,
+ qp_points->via.raw,
+ qp_len->via.int64);
+ }
+ else
+ {
+ siridb_points_unzip_string(
+ points,
+ qp_points->via.raw,
+ qp_len->via.int64,
+ NULL, NULL, 0);
+ }
+ }
+ else
+ {
+ points->len = qp_len->via.int64;
+ memcpy(points->data, qp_points->via.raw, qp_points->len);
+ }
+
+ if (ct_add(q_select->result, (char *) qp_name->via.raw, points))
+ {
+ siridb_points_free(points);
+ }
+ else
+ {
+ q_select->n += points->len;
+ }
+ }
+
+ qp_next(unpacker, NULL); /* QP_ARRAY_CLOSE */
+ }
+}
+
+static void on_select_unpack_merged_points(
+ qp_unpacker_t * unpacker,
+ query_select_t * q_select,
+ qp_obj_t * qp_name,
+ qp_obj_t * qp_tp,
+ qp_obj_t * qp_len,
+ qp_obj_t * qp_points,
+ uint32_t select_points_limit)
+{
+ siridb_points_t * points;
+
+ while ( qp_is_raw(qp_next(unpacker, qp_name)) &&
+#if DEBUG
+ qp_is_raw_term(qp_name) &&
+#endif
+ qp_is_array(qp_next(unpacker, NULL)))
+
+ {
+ slist_t ** plist = (slist_t **) ct_getaddr(
+ q_select->result,
+ (const char *) qp_name->via.raw);
+
+ while ( q_select->n <= select_points_limit &&
+ qp_is_array(qp_next(unpacker, NULL)) &&
+ qp_is_int(qp_next(unpacker, qp_tp)) &&
+ qp_is_int(qp_next(unpacker, qp_len)) &&
+ qp_is_raw(qp_next(unpacker, qp_points)))
+ {
+
+ points = siridb_points_new(qp_len->via.int64, qp_tp->via.int64);
+
+ if (points != NULL)
+ {
+ if (points->tp == TP_STRING)
+ {
+ if (qp_len->via.int64 < POINTS_ZIP_THRESHOLD)
+ {
+ siridb_points_unzip_string_raw(
+ points,
+ qp_points->via.raw,
+ qp_len->via.int64);
+ }
+ else
+ {
+ siridb_points_unzip_string(
+ points,
+ qp_points->via.raw,
+ qp_len->via.int64,
+ NULL, NULL, 0);
+ }
+ }
+ else
+ {
+ points->len = qp_len->via.int64;
+ memcpy(points->data, qp_points->via.raw, qp_points->len);
+ }
+
+ if (slist_append_safe(plist, points))
+ {
+ siridb_points_free(points);
+ }
+ else
+ {
+ q_select->n += points->len;
+ }
+ }
+
+ qp_next(unpacker, NULL); /* QP_ARRAY_CLOSE */
+ }
+ }
+}
+
+static int values_list_groups(siridb_group_t * group, uv_async_t * handle)
+{
+ siridb_query_t * query = (siridb_query_t *) handle->data;
+ cexpr_t * where_expr = ((query_list_t *) query->data)->where_expr;
+ cexpr_cb_t cb = (cexpr_cb_t) siridb_group_cexpr_cb;
+ slist_t * props = ((query_list_t *) query->data)->props;
+
+ if (where_expr == NULL || cexpr_run(where_expr, cb, group))
+ {
+ size_t i;
+ qp_add_type(query->packer, QP_ARRAY_OPEN);
+
+ for (i = 0; i < props->len; i++)
+ {
+ siridb_group_prop(
+ group,
+ query->packer,
+ *((uint32_t *) props->data[i]));
+ }
+
+ qp_add_type(query->packer, QP_ARRAY_CLOSE);
+
+ return 1;
+ }
+
+ return 0;
+}
+
+static int values_count_groups(siridb_group_t * group, uv_async_t * handle)
+{
+ siridb_query_t * query = (siridb_query_t *) handle->data;
+
+ return cexpr_run(
+ ((query_list_t *) query->data)->where_expr,
+ (cexpr_cb_t) siridb_group_cexpr_cb,
+ group);
+}
+
+static void finish_list_groups(uv_async_t * handle)
+{
+ siridb_query_t * query = (siridb_query_t *) handle->data;
+ query_list_t * q_list = (query_list_t *) query->data;
+ siridb_t * siridb = query->client->siridb;
+
+ if (q_list->props == NULL)
+ {
+ q_list->props = slist_new(1);
+ if (q_list->props == NULL)
+ {
+ MEM_ERR_RET
+ }
+ slist_append(q_list->props, &GID_K_NAME);
+ qp_add_raw(query->packer, (const unsigned char *) "name", 4);
+ }
+
+ qp_add_type(query->packer, QP_ARRAY_CLOSE);
+
+ qp_add_raw(query->packer, (const unsigned char *) "groups", 6);
+ qp_add_type(query->packer, QP_ARRAY_OPEN);
+
+ ct_valuesn(
+ siridb->groups->groups,
+ &q_list->limit,
+ (ct_val_cb) values_list_groups,
+ handle);
+
+ qp_add_type(query->packer, QP_ARRAY_CLOSE);
+
+ SIRIPARSER_ASYNC_NEXT_NODE
+}
+
+static void finish_count_groups(uv_async_t * handle)
+{
+ siridb_query_t * query = (siridb_query_t *) handle->data;
+ query_count_t * q_count = (query_count_t *) query->data;
+ siridb_t * siridb = query->client->siridb;
+
+ /* Note: ct_values(..values_count_groups..) can only result in a positive
+ * value.
+ */
+ size_t n = (q_count->where_expr == NULL) ?
+ siridb->groups->groups->len :
+ (size_t) ct_values(
+ siridb->groups->groups,
+ (ct_val_cb) values_count_groups,
+ handle);
+
+ qp_add_raw(query->packer, (const unsigned char *) "groups", 6);
+
+ qp_add_int64(query->packer, n);
+
+ SIRIPARSER_ASYNC_NEXT_NODE
+}
assert (siridb->server != NULL);
#endif
- siridb->pools = (siridb_pools_t *) malloc(sizeof(siridb_pools_t));
+ siridb->pools = malloc(sizeof(siridb_pools_t));
if (siridb->pools == NULL)
{
ERR_ALLOC
siridb->pools->len = max_pool + 1;
/* allocate memory for all pools */
- siridb->pools->pool = (siridb_pool_t *)
- malloc(sizeof(siridb_pool_t) * siridb->pools->len);
+ siridb->pools->pool = malloc(sizeof(siridb_pool_t) * siridb->pools->len);
if (siridb->pools->pool == NULL)
{
#include <siri/db/time.h>
#include <siri/grammar/grammar.h>
#include <siri/db/fifo.h>
+#include <siri/net/tcp.h>
#include <siri/siri.h>
#include <siri/version.h>
#include <stdio.h>
int map)
{
SIRIDB_PROP_MAP("ip_support", 10)
- qp_add_string(packer, sirinet_socket_ip_support_str(siri.cfg->ip_support));
+ qp_add_string(packer, sirinet_tcp_ip_support_str(siri.cfg->ip_support));
}
static void prop_libuv(
--- /dev/null
+/*
+ * queries.c - Querie helpers for listener
+ *
+ * author : Jeroen van der Heijden
+ * email : jeroen@transceptor.technology
+ * copyright : 2016, Transceptor Technology
+ *
+ * changes
+ * - initial version, 03-05-2016
+ *
+ */
+#include <assert.h>
+#include <logger/logger.h>
+#include <siri/db/aggregate.h>
+#include <siri/db/query.h>
+#include <siri/db/shard.h>
+#include <siri/db/queries.h>
+#include <stddef.h>
+#include <stdlib.h>
+
+#define DEFAULT_LIST_LIMIT 1000
+
+#define QUERIES_NEW(q) \
+q->flags = 0; \
+q->series_map = NULL; \
+q->series_tmp = NULL; \
+q->slist = NULL; \
+q->slist_index = 0; \
+q->pmap = NULL; \
+q->update_cb = NULL; \
+q->where_expr = NULL; \
+q->regex = NULL; \
+q->match_data = NULL;
+
+
+#define QUERIES_FREE(q, handle) \
+if (q->series_map != NULL) \
+{ \
+ imap_free( \
+ q->series_map, \
+ (imap_free_cb) &siridb__series_decref); \
+} \
+if (q->series_tmp != NULL) \
+{ \
+ imap_free( \
+ q->series_tmp, \
+ (imap_free_cb) &siridb__series_decref); \
+} \
+if (q->slist != NULL) \
+{ \
+ siridb_series_t * series; \
+ for (; q->slist_index < q->slist->len; q->slist_index++) \
+ { \
+ series = (siridb_series_t *) q->slist->data[q->slist_index]; \
+ siridb_series_decref(series); \
+ } \
+ slist_free(q->slist); \
+} \
+if (q->where_expr != NULL) \
+{ \
+ cexpr_free(q->where_expr); \
+} \
+if (q->pmap != NULL) \
+{ \
+ imap_free(q->pmap, NULL); \
+} \
+pcre2_code_free(q->regex); \
+pcre2_match_data_free(q->match_data); \
+free(q); \
+siridb_query_free(handle);
+
+static void QUERIES_free_merge_result(slist_t * plist);
+
+query_select_t * query_select_new(void)
+{
+ query_select_t * q_select =
+ (query_select_t *) malloc(sizeof(query_select_t));
+
+ if (q_select == NULL)
+ {
+ return NULL;
+ }
+ QUERIES_NEW(q_select)
+
+ q_select->tp = QUERIES_SELECT;
+ q_select->start_ts = NULL;
+ q_select->end_ts = NULL;
+ q_select->presuf = NULL;
+ q_select->merge_as = NULL;
+ q_select->n = 0;
+ q_select->nselects = 1; /* we have at least one select function */
+ q_select->points_map = NULL;
+ q_select->alist = NULL;
+ q_select->mlist = NULL;
+ q_select->result = ct_new();
+
+ if (q_select->result == NULL)
+ {
+ free(q_select);
+ return NULL;
+ }
+
+ return q_select;
+}
+
+query_alter_t * query_alter_new(void)
+{
+ query_alter_t * q_alter =
+ (query_alter_t *) malloc(sizeof(query_alter_t));
+
+ if (q_alter == NULL)
+ {
+ return NULL;
+ }
+
+ QUERIES_NEW(q_alter)
+
+ q_alter->tp = QUERIES_ALTER;
+ q_alter->alter_tp = QUERY_ALTER_NONE;
+ q_alter->via.dummy = NULL;
+ q_alter->n = 0;
+
+ return q_alter;
+}
+
+query_count_t * query_count_new(void)
+{
+ query_count_t * q_count =
+ (query_count_t *) malloc(sizeof(query_count_t));
+
+ if (q_count == NULL)
+ {
+ return NULL;
+ }
+
+ QUERIES_NEW(q_count)
+
+ q_count->tp = QUERIES_COUNT;
+ q_count->n = 0;
+
+ return q_count;
+}
+
+query_drop_t * query_drop_new(void)
+{
+ query_drop_t * q_drop =
+ (query_drop_t *) malloc(sizeof(query_drop_t));
+
+ if (q_drop == NULL)
+ {
+ return NULL;
+ }
+
+ QUERIES_NEW(q_drop)
+
+ q_drop->tp = QUERIES_DROP;
+ q_drop->n = 0;
+ q_drop->flags = 0;
+ q_drop->shards_list = NULL;
+
+ return q_drop;
+}
+
+query_list_t * query_list_new(void)
+{
+ query_list_t * q_list =
+ (query_list_t *) malloc(sizeof(query_list_t));
+
+ if (q_list == NULL)
+ {
+ return NULL;
+ }
+
+ QUERIES_NEW(q_list)
+
+ q_list->tp = QUERIES_LIST;
+ q_list->props = NULL;
+ q_list->limit = DEFAULT_LIST_LIMIT;
+
+ return q_list;
+}
+
+void query_alter_free(uv_handle_t * handle)
+{
+ query_alter_t * q_alter =
+ (query_alter_t *) ((siridb_query_t *) handle->data)->data;
+
+ switch (q_alter->alter_tp)
+ {
+ case QUERY_ALTER_NONE:
+ case QUERY_ALTER_DATABASE:
+ case QUERY_ALTER_SERVERS:
+ break;
+ case QUERY_ALTER_GROUP:
+ siridb_group_decref(q_alter->via.group);
+ break;
+ case QUERY_ALTER_SERVER:
+ siridb_server_decref(q_alter->via.server);
+ break;
+ case QUERY_ALTER_USER:
+ siridb_user_decref(q_alter->via.user);
+ break;
+ default:
+ assert(0);
+ }
+
+ QUERIES_FREE(q_alter, handle)
+}
+
+void query_count_free(uv_handle_t * handle)
+{
+ query_count_t * q_count =
+ (query_count_t *) ((siridb_query_t *) handle->data)->data;
+
+ QUERIES_FREE(q_count, handle)
+}
+
+void query_drop_free(uv_handle_t * handle)
+{
+ query_drop_t * q_drop =
+ (query_drop_t *) ((siridb_query_t *) handle->data)->data;
+
+ if (q_drop->shards_list != NULL)
+ {
+ siridb_shard_t * shard;
+ while (q_drop->shards_list->len)
+ {
+ shard = (siridb_shard_t *) slist_pop(q_drop->shards_list);
+ siridb_shard_decref(shard);
+ }
+
+ slist_free(q_drop->shards_list);
+ }
+
+ QUERIES_FREE(q_drop, handle)
+}
+
+void query_list_free(uv_handle_t * handle)
+{
+ query_list_t * q_list =
+ (query_list_t *) ((siridb_query_t *) handle->data)->data;
+
+ if (q_list->props != NULL)
+ {
+ slist_free(q_list->props);
+ }
+
+ QUERIES_FREE(q_list, handle)
+}
+
+void query_select_free(uv_handle_t * handle)
+{
+ query_select_t * q_select =
+ (query_select_t *) ((siridb_query_t *) handle->data)->data;
+
+ siridb_presuf_free(q_select->presuf);
+
+ if (q_select->points_map != NULL)
+ {
+ imap_free(q_select->points_map, (imap_free_cb) &siridb_points_free);
+ }
+
+ if (q_select->result != NULL)
+ {
+ if (q_select->merge_as == NULL)
+ {
+ ct_free(q_select->result, (ct_free_cb) &siridb_points_free);
+ }
+ else
+ {
+ ct_free(q_select->result, (ct_free_cb) &QUERIES_free_merge_result);
+ }
+ }
+
+ free(q_select->merge_as);
+
+ if (q_select->alist != NULL)
+ {
+ siridb_aggregate_list_free(q_select->alist);
+ }
+
+ if (q_select->mlist != NULL)
+ {
+ siridb_aggregate_list_free(q_select->mlist);
+ }
+
+ QUERIES_FREE(q_select, handle)
+}
+
+void query_help_free(uv_handle_t * handle)
+{
+ /* used as char to hold a string */
+ free(((siridb_query_t *) handle->data)->data);
+
+ /* normal call-back */
+ siridb_query_free(handle);
+}
+
+static void QUERIES_free_merge_result(slist_t * plist)
+{
+ size_t i;
+ for (i = 0; i < plist->len; i ++)
+ {
+ siridb_points_free(plist->data[i]);
+ }
+ free(plist);
+}
#include <siri/db/servers.h>
#include <siri/db/time.h>
#include <siri/db/walker.h>
+#include <siri/db/listener.h>
+#include <siri/db/queries.h>
#include <siri/net/clserver.h>
#include <siri/net/pkg.h>
#include <siri/net/clserver.h>
-#include <siri/parser/listener.h>
-#include <siri/parser/queries.h>
#include <siri/siri.h>
#include <strextra/strextra.h>
#include <string.h>
*/
void siridb_query_run(
uint16_t pid,
- uv_stream_t * client,
+ sirinet_stream_t * client,
const char * q,
size_t q_len,
float factor,
query->pid = pid;
/* increment client reference counter */
- sirinet_client_incref(client);
+ sirinet_stream_incref(client);
query->client = client;
query->flags = flags;
log_debug("Parsing query (%d): %s", query->flags, query->q);
}
- CLIENT_SIRIDB(query->client, siridb)
-
/* increment active tasks */
- siridb_tasks_inc(siridb->tasks);
+ siridb_tasks_inc(client->siridb->tasks);
/* send next call */
uv_async_init(siri.loop, handle, (uv_async_cb) QUERY_parse);
void siridb_query_free(uv_handle_t * handle)
{
siridb_query_t * query = (siridb_query_t *) handle->data;
- CLIENT_SIRIDB(query->client, siridb)
+ siridb_t * siridb = query->client->siridb;
/* decrement active tasks */
siridb_tasks_dec(siridb->tasks);
}
/* decrement client reference counter */
- sirinet_client_decref(query->client);
+ sirinet_stream_decref(query->client);
/* free query */
free(query);
query->pid,
CPROTO_RES_QUERY);
- sirinet_pkg_send((uv_stream_t *) query->client, pkg);
+ sirinet_pkg_send(query->client, pkg);
query->packer = NULL;
if (package != NULL)
{
/* ignore result code, signal can be raised */
- sirinet_pkg_send((uv_stream_t *) query->client, package);
+ sirinet_pkg_send(query->client, package);
}
uv_close((uv_handle_t *) handle, siri_async_close);
}
int flags)
{
siridb_query_t * query = (siridb_query_t *) handle->data;
- CLIENT_SIRIDB(query->client, siridb)
+ siridb_t * siridb = query->client->siridb;
/*
* the size is important here, we will use the alloc_size to guess the
#ifndef DEBUG
/* production version returns timestamp now */
- CLIENT_SIRIDB(query->client, siridb)
+ siridb_t * siridb = query->client->siridb;
qp_add_raw(query->packer, (const unsigned char *) "calc", 4);
uint64_t ts = siridb_time_now(siridb, query->start);
{
int rc;
siridb_query_t * query = (siridb_query_t *) handle->data;
- CLIENT_SIRIDB(query->client, siridb)
+ siridb_t * siridb = query->client->siridb;
siridb_walker_t * walker = siridb_walker_new(
siridb,
/* reserve 200 extra chars */
char buffer[packer->alloc_size];
size_t size = packer->alloc_size;
-
- CLIENT_SIRIDB(query->client, siridb)
+ siridb_t * siridb = query->client->siridb;
rc = QUERY_rebuild(
siridb,
*/
if (gid != CLERI_NONE)
{
- if ( (func = siriparser_listen_enter[gid]) != NULL &&
+ if ( (func = siridb_listen_enter[gid]) != NULL &&
siridb_walker_append(walker, node, func))
{
return EXPR_MEM_ALLOC_ERR;
}
- if ( (func = siriparser_listen_exit[gid]) != NULL &&
+ if ( (func = siridb_listen_exit[gid]) != NULL &&
siridb_walker_insert(walker, node, func))
{
return EXPR_MEM_ALLOC_ERR;
#include <logger/logger.h>
#include <siri/db/buffer.h>
#include <siri/db/db.h>
+#include <siri/db/misc.h>
#include <siri/db/series.h>
#include <siri/db/shard.h>
#include <siri/db/shards.h>
}
else if (fflush(siridb->dropped_fp))
{
- SIRIDB_GET_FN(fn, siridb->dbpath, SIRIDB_DROPPED_FN)
+ siridb_misc_get_fn(fn, siridb->dbpath, SIRIDB_DROPPED_FN)
log_critical("Could not flush dropped file: '%s'", fn);
rc = -1;
}
int siridb_series_open_store(siridb_t * siridb)
{
/* macro get series file name */
- SIRIDB_GET_FN(fn, siridb->dbpath, SIRIDB_SERIES_FN)
+ siridb_misc_get_fn(fn, siridb->dbpath, SIRIDB_SERIES_FN)
if ((siridb->store = qp_open(fn, "a")) == NULL)
{
log_debug("Cleanup series file");
/* macro get series file name */
- SIRIDB_GET_FN(fn, siridb->dbpath, SIRIDB_SERIES_FN)
+ siridb_misc_get_fn(fn, siridb->dbpath, SIRIDB_SERIES_FN)
if ((fpacker = qp_open(fn, "w")) == NULL)
{
log_debug("Loading dropped series");
- SIRIDB_GET_FN(fn, siridb->dbpath, SIRIDB_DROPPED_FN)
+ siridb_misc_get_fn(fn, siridb->dbpath, SIRIDB_DROPPED_FN)
if ((fp = fopen(fn, "r")) == NULL)
{
assert(siridb->max_series_id == 0);
/* get series file name */
- SIRIDB_GET_FN(fn, siridb->dbpath, SIRIDB_SERIES_FN)
+ siridb_misc_get_fn(fn, siridb->dbpath, SIRIDB_SERIES_FN)
if (!xpath_file_exist(fn))
{
}
/* unpacker will be freed in case schema check fails */
- siridb_schema_check(SIRIDB_SERIES_SCHEMA)
+ siridb_misc_schema_check(SIRIDB_SERIES_SCHEMA)
while (qp_next(unpacker, NULL) == QP_ARRAY3 &&
qp_next(unpacker, &qp_series_name) == QP_RAW &&
*/
static int SERIES_open_new_dropped_file(siridb_t * siridb)
{
- SIRIDB_GET_FN(fn, siridb->dbpath, SIRIDB_DROPPED_FN)
+ siridb_misc_get_fn(fn, siridb->dbpath, SIRIDB_DROPPED_FN)
if ((siridb->dropped_fp = fopen(fn, "w")) == NULL)
{
*/
static int SERIES_open_dropped_file(siridb_t * siridb)
{
- SIRIDB_GET_FN(fn, siridb->dbpath, SIRIDB_DROPPED_FN)
+ siridb_misc_get_fn(fn, siridb->dbpath, SIRIDB_DROPPED_FN)
if ((siridb->dropped_fp = fopen(fn, "a")) == NULL)
{
FILE * fp;
uint32_t max_series_id = 0;
- SIRIDB_GET_FN(fn, siridb->dbpath, SIRIDB_MAX_SERIES_ID_FN)
+ siridb_misc_get_fn(fn, siridb->dbpath, SIRIDB_MAX_SERIES_ID_FN)
if ((fp = fopen(fn, "r")) != NULL)
{
#include <siri/db/fifo.h>
#include <siri/err.h>
#include <siri/net/promise.h>
-#include <siri/net/socket.h>
+#include <siri/net/stream.h>
+#include <siri/net/tcp.h>
#include <siri/siri.h>
#include <siri/version.h>
#include <strextra/strextra.h>
siridb_server_t * server,
int ai_family,
uv_getaddrinfo_cb getaddrinfo_cb);
-static void SERVER_on_data(uv_stream_t * client, sirinet_pkg_t * pkg);
+static void SERVER_on_data(sirinet_stream_t * client, sirinet_pkg_t * pkg);
static void SERVER_cancel_promise(sirinet_promise_t * promise);
static void SERVER_upd_flag_queue_full(siridb_server_t * server);
/* we set the promises later because we don't need one for self */
server->promises = NULL;
- server->socket = NULL;
+ server->client = NULL;
/* sets address:port to name property */
if (SERVER_update_name(server))
int flags)
{
#if DEBUG
- assert (server->socket != NULL);
+ assert (server->client != NULL);
assert (server->promises != NULL);
assert (cb != NULL);
#endif
uv_write(
req,
- (uv_stream_t *) server->socket,
+ server->client->stream,
&wrbuf,
1,
SERVER_write_cb);
{
#if DEBUG
- assert (server->socket != NULL);
+ assert (server->client != NULL);
assert (siridb_server_is_online(server));
#endif
- sirinet_socket_t * ssocket = server->socket->data;
+ sirinet_stream_t * client = server->client;
#if DEBUG
- assert (ssocket->siridb != NULL);
+ assert (client->siridb != NULL);
#endif
- int16_t n = ssocket->siridb->server->flags;
+ int16_t n = client->siridb->server->flags;
QP_PACK_INT16(buffer, n)
sirinet_pkg_t * pkg = sirinet_pkg_new(0, 3, BPROTO_FLAGS_UPDATE, buffer);
{
#if DEBUG
/* server->socket must be NULL at this point */
- assert (server->socket == NULL);
+ assert (server->client == NULL);
#endif
- server->socket = sirinet_socket_new(SOCKET_SERVER, &SERVER_on_data);
+ server->client = sirinet_stream_new(STREAM_TCP_SERVER, &SERVER_on_data);
- if (server->socket != NULL)
+ if (server->client != NULL)
{
struct in_addr sa;
struct in6_addr sa6;
- sirinet_socket_t * ssocket = (sirinet_socket_t *) server->socket->data;
- ssocket->origin = server;
- ssocket->siridb = siridb;
+ server->client->origin = server;
+ server->client->siridb = siridb;
siridb_server_incref(server);
- uv_tcp_init(siri.loop, server->socket);
+ uv_tcp_init(siri.loop, (uv_tcp_t *) server->client->stream);
if (inet_pton(AF_INET, server->address, &sa))
{
if (req == NULL)
{
ERR_ALLOC
- sirinet_socket_decref(server->socket);
+ sirinet_stream_decref(server->client);
}
else
{
uv_ip4_addr(server->address, server->port, &dest);
uv_tcp_connect(
req,
- server->socket,
+ (uv_tcp_t *) server->client->stream,
(const struct sockaddr *) &dest,
SERVER_on_connect);
}
if (req == NULL)
{
ERR_ALLOC
- sirinet_socket_decref(server->socket);
+ sirinet_stream_decref(server->client);
}
else
{
uv_ip6_addr(server->address, server->port, &dest6);
uv_tcp_connect(
req,
- server->socket,
+ (uv_tcp_t *) server->client->stream,
(const struct sockaddr *) &dest6,
SERVER_on_connect);
}
dns_req_family_map[siri.cfg->ip_support],
SERVER_on_resolved))
{
- sirinet_socket_decref(server->socket);
+ sirinet_stream_decref(server->client);
}
}
}
server->name,
uv_err_name(status));
- sirinet_socket_decref(server->socket);
+ sirinet_stream_decref(server->client);
}
else
{
{
uv_tcp_connect(
req,
- server->socket,
+ (uv_tcp_t *) server->client->stream,
(const struct sockaddr *) res->ai_addr,
SERVER_on_connect);
}
*/
static void SERVER_on_connect(uv_connect_t * req, int status)
{
- sirinet_socket_t * ssocket = req->handle->data;
- siridb_server_t * server = ssocket->origin;
+ sirinet_stream_t * client = req->handle->data;
+ siridb_t * siridb = client->siridb;
+ siridb_server_t * server = client->origin;
if (status == 0)
{
uv_read_start(
req->handle,
- sirinet_socket_alloc_buffer,
- sirinet_socket_on_data);
+ sirinet_stream_alloc_buffer,
+ sirinet_stream_on_data);
sirinet_pkg_t * pkg;
qp_packer_t * packer = sirinet_packer_new(512);
{
if (qp_add_type(packer, QP_ARRAY_OPEN) ||
qp_add_raw(packer, (const unsigned char *)
- ssocket->siridb->server->uuid, 16) ||
- qp_add_string_term(packer, ssocket->siridb->dbname) ||
- qp_add_int16(packer, ssocket->siridb->server->flags) ||
+ client->siridb->server->uuid, 16) ||
+ qp_add_string_term(packer, siridb->dbname) ||
+ qp_add_int16(packer, siridb->server->flags) ||
qp_add_string_term(packer, SIRIDB_VERSION) ||
qp_add_string_term(packer, SIRIDB_MINIMAL_VERSION) ||
qp_add_int8(packer, siri.cfg->ip_support) ||
qp_add_string_term(packer, uv_version_string()) ||
- qp_add_string_term(packer, ssocket->siridb->dbpath) ||
- qp_add_string_term(packer, ssocket->siridb->buffer_path) ||
- qp_add_int64(packer, (int64_t) ssocket->siridb->buffer_size) ||
+ qp_add_string_term(packer, siridb->dbpath) ||
+ qp_add_string_term(packer, siridb->buffer_path) ||
+ qp_add_int64(packer, (int64_t) siridb->buffer_size) ||
qp_add_int32(packer, (int32_t) siri.startup_time) ||
- qp_add_string_term(packer, ssocket->siridb->server->address) ||
- qp_add_int32(packer, (int32_t) ssocket->siridb->server->port))
+ qp_add_string_term(packer, siridb->server->address) ||
+ qp_add_int32(packer, (int32_t) siridb->server->port))
{
qp_packer_free(packer);
}
server->name,
uv_strerror(status));
- sirinet_socket_decref(req->handle);
+ sirinet_stream_decref(client);
}
free(req);
}
* on-data call-back function.
*In case the promise is found, promise->cb() will be called.
*/
-static void SERVER_on_data(uv_stream_t * client, sirinet_pkg_t * pkg)
+static void SERVER_on_data(sirinet_stream_t * client, sirinet_pkg_t * pkg)
{
- sirinet_socket_t * ssocket = client->data;
- siridb_server_t * server = ssocket->origin;
+ siridb_server_t * server = client->origin;
sirinet_promise_t * promise = imap_pop(server->promises, pkg->pid);
log_debug(
case CLERI_GID_K_IP_SUPPORT:
return cexpr_str_cmp(
cond->operator,
- sirinet_socket_ip_support_str(
+ sirinet_tcp_ip_support_str(
(wserver->siridb->server == wserver->server) ?
siri.cfg->ip_support :
wserver->server->ip_support),
return cexpr_bool_cmp(
cond->operator,
( wserver->siridb->server == wserver->server ||
- wserver->server->socket != NULL),
+ wserver->server->client != NULL),
cond->int64);
case CLERI_GID_K_POOL:
}
if ( (status || pkg->tp != BPROTO_AUTH_SUCCESS) &&
- promise->server->socket != NULL)
+ promise->server->client != NULL)
{
- sirinet_socket_decref(promise->server->socket);
+ sirinet_stream_decref(promise->server->client);
}
/* we must free the promise */
promise->server->name,
sirinet_promise_strstatus(status));
- if (promise->server->socket != NULL)
+ if (promise->server->client != NULL)
{
- sirinet_socket_t * ssocket =
- (sirinet_socket_t *) promise->server->socket->data;
+ siridb_t * siridb = promise->server->client->siridb;
siridb_server_t * replica = siridb_servers_by_replica(
- ssocket->siridb->servers,
+ siridb->servers,
promise->server);
if (replica != NULL && (
- replica == ssocket->siridb->server ||
+ replica == siridb->server ||
siridb_server_is_accessible(replica)))
{
/* we only set the status unavailable if we have an accessible
#include <siri/db/query.h>
#include <siri/db/server.h>
#include <siri/db/servers.h>
+#include <siri/db/misc.h>
#include <siri/err.h>
#include <siri/net/promises.h>
-#include <siri/parser/queries.h>
+#include <siri/net/tcp.h>
+#include <siri/db/queries.h>
#include <siri/siri.h>
#include <siri/version.h>
#include <xpath/xpath.h>
}
/* get servers file name */
- SIRIDB_GET_FN(fn, siridb->dbpath, SIRIDB_SERVERS_FN)
+ siridb_misc_get_fn(fn, siridb->dbpath, SIRIDB_SERVERS_FN)
if (!xpath_file_exist(fn))
{
}
/* unpacker will be freed in case macro fails */
- siridb_schema_check(SIRIDB_SERVERS_SCHEMA)
+ siridb_misc_schema_check(SIRIDB_SERVERS_SCHEMA)
int rc = 0;
ssize_t siridb_servers_get_file(char ** buffer, siridb_t * siridb)
{
/* get servers file name */
- SIRIDB_GET_FN(fn, siridb->dbpath, SIRIDB_SERVERS_FN)
+ siridb_misc_get_fn(fn, siridb->dbpath, SIRIDB_SERVERS_FN)
return xpath_get_content(buffer, fn);
}
int siridb_servers_list(siridb_server_t * server, uv_async_t * handle)
{
- siridb_query_t * query = (siridb_query_t *) handle->data;
- slist_t * props = ((query_list_t *) query->data)->props;
- siridb_t * siridb = ((sirinet_socket_t *) query->client->data)->siridb;
- cexpr_t * where_expr = ((query_list_t *) query->data)->where_expr;
+ siridb_query_t * query = handle->data;
+ query_list_t * qlist = query->data;
+ slist_t * props = qlist->props;
+ siridb_t * siridb = query->client->siridb;
+ cexpr_t * where_expr = qlist->where_expr;
size_t i;
siridb_server_walker_t wserver = {
case CLERI_GID_K_IP_SUPPORT:
qp_add_string(
query->packer,
- sirinet_socket_ip_support_str((siridb->server == server) ?
+ sirinet_tcp_ip_support_str((siridb->server == server) ?
siri.cfg->ip_support : server->ip_support));
break;
case CLERI_GID_K_LIBUV:
case CLERI_GID_K_ONLINE:
qp_add_type(
query->packer,
- (siridb->server == server || server->socket != NULL) ?
+ (siridb->server == server || server->client != NULL) ?
QP_TRUE : QP_FALSE);
break;
case CLERI_GID_K_POOL:
qp_fpacker_t * fpacker;
/* get servers file name */
- SIRIDB_GET_FN(fn, siridb->dbpath, SIRIDB_SERVERS_FN)
+ siridb_misc_get_fn(fn, siridb->dbpath, SIRIDB_SERVERS_FN)
if ((fpacker = qp_open(fn, "w")) == NULL)
{
#include <logger/logger.h>
#include <siri/db/shard.h>
#include <siri/db/shards.h>
+#include <siri/db/misc.h>
#include <siri/siri.h>
#include <stdbool.h>
#include <string.h>
log_info("Loading shards");
- SIRIDB_GET_FN(path, siridb->dbpath, SIRIDB_SHARDS_PATH);
+ siridb_misc_get_fn(path, siridb->dbpath, SIRIDB_SHARDS_PATH);
if (strlen(path) >= SIRI_PATH_MAX - SIRIDB_MAX_SHARD_FN_LEN - 1)
{
#include <qpack/qpack.h>
#include <siri/db/query.h>
#include <siri/db/users.h>
+#include <siri/db/misc.h>
#include <siri/err.h>
#include <stdlib.h>
#include <strextra/strextra.h>
}
/* get user access file name */
- SIRIDB_GET_FN(fn, siridb->dbpath, SIRIDB_USERS_FN)
+ siridb_misc_get_fn(fn, siridb->dbpath, SIRIDB_USERS_FN)
if (!xpath_file_exist(fn))
{
}
/* unpacker will be freed in case macro fails */
- siridb_schema_check(SIRIDB_USERS_SCHEMA)
+ siridb_misc_schema_check(SIRIDB_USERS_SCHEMA)
int rc = 0;
while (qp_is_array(qp_next(unpacker, NULL)) &&
ssize_t siridb_users_get_file(char ** buffer, siridb_t * siridb)
{
/* get users file name */
- SIRIDB_GET_FN(fn, siridb->dbpath, SIRIDB_USERS_FN)
+ siridb_misc_get_fn(fn, siridb->dbpath, SIRIDB_USERS_FN)
return xpath_get_content(buffer, fn);
}
qp_fpacker_t * fpacker;
/* get user access file name */
- SIRIDB_GET_FN(fn, siridb->dbpath, SIRIDB_USERS_FN)
+ siridb_misc_get_fn(fn, siridb->dbpath, SIRIDB_USERS_FN)
if (
/* open a new user file */
{
server = (siridb_server_t *) server_node->data;
- if (server != siridb->server && server->socket == NULL)
+ if (server != siridb->server && server->client == NULL)
{
siridb_server_connect(siridb, server);
}
#include <siri/net/bserver.h>
#include <siri/net/pkg.h>
#include <siri/net/protocol.h>
-#include <siri/net/socket.h>
+#include <siri/net/stream.h>
+#include <siri/net/tcp.h>
#include <siri/optimize.h>
#include <siri/siri.h>
#include <stdlib.h>
#define DEFAULT_BACKLOG 128
-#define SERVER_CHECK_AUTHENTICATED(server) \
-siridb_server_t * server = ((sirinet_socket_t * ) client->data)->origin; \
-if (!(server->flags & SERVER_FLAG_AUTHENTICATED)) \
-{ \
- sirinet_pkg_t * package; \
- package = sirinet_pkg_new(pkg->pid, 0, BPROTO_ERR_NOT_AUTHENTICATED, NULL); \
- sirinet_pkg_send((uv_stream_t *) client, package); \
- return; \
+#define SERVER_CHECK_AUTHENTICATED(client__, server__) \
+siridb_server_t * server__ = (client__)->origin; \
+if (!(server__->flags & SERVER_FLAG_AUTHENTICATED)) \
+{ \
+ sirinet_pkg_t * package; \
+ package = sirinet_pkg_new( \
+ pkg->pid, 0, BPROTO_ERR_NOT_AUTHENTICATED, NULL); \
+ sirinet_pkg_send(client, package); \
+ return; \
}
static void BSERVER_flags_update(
siridb_server_t * server,
int64_t flags);
static void on_new_connection(uv_stream_t * server, int status);
-static void on_data(uv_stream_t * client, sirinet_pkg_t * pkg);
-static void on_auth_request(uv_stream_t * client, sirinet_pkg_t * pkg);
-static void on_flags_update(uv_stream_t * client, sirinet_pkg_t * pkg);
-static void on_log_level_update(uv_stream_t * client, sirinet_pkg_t * pkg);
-static void on_repl_finished(uv_stream_t * client, sirinet_pkg_t * pkg);
-static void on_query(uv_stream_t * client, sirinet_pkg_t * pkg, int flags);
-static void on_insert(uv_stream_t * client, sirinet_pkg_t * pkg, int flags);
-static void on_register_server(uv_stream_t * client, sirinet_pkg_t * pkg);
-static void on_drop_series(uv_stream_t * client, sirinet_pkg_t * pkg);
-static void on_req_groups(uv_stream_t * client, sirinet_pkg_t * pkg);
-static void on_enable_backup_mode(uv_stream_t * client, sirinet_pkg_t * pkg);
-static void on_disable_backup_mode(uv_stream_t * client, sirinet_pkg_t * pkg);
+static void on_data(sirinet_stream_t * client, sirinet_pkg_t * pkg);
+static void on_auth_request(sirinet_stream_t * client, sirinet_pkg_t * pkg);
+static void on_flags_update(sirinet_stream_t * client, sirinet_pkg_t * pkg);
+static void on_log_level_update(
+ sirinet_stream_t * client,
+ sirinet_pkg_t * pkg);
+static void on_repl_finished(sirinet_stream_t * client, sirinet_pkg_t * pkg);
+static void on_query(
+ sirinet_stream_t * client,
+ sirinet_pkg_t * pkg, int flags);
+static void on_insert(
+ sirinet_stream_t * client,
+ sirinet_pkg_t * pkg, int flags);
+static void on_register_server(sirinet_stream_t * client, sirinet_pkg_t * pkg);
+static void on_drop_series(sirinet_stream_t * client, sirinet_pkg_t * pkg);
+static void on_req_groups(sirinet_stream_t * client, sirinet_pkg_t * pkg);
+static void on_enable_backup_mode(
+ sirinet_stream_t * client,
+ sirinet_pkg_t * pkg);
+static void on_disable_backup_mode(
+ sirinet_stream_t * client,
+ sirinet_pkg_t * pkg);
static uv_loop_t * loop = NULL;
static struct sockaddr_storage server_addr;
log_debug("Received a back-end server connection request.");
- uv_tcp_t * client =
- sirinet_socket_new(SOCKET_BACKEND, (on_data_cb_t) &on_data);
+ sirinet_stream_t * client = sirinet_stream_new(
+ STREAM_TCP_BACKEND, (on_data_cb_t) &on_data);
+
if (client != NULL)
{
- uv_tcp_init(loop, client);
+ uv_tcp_init(loop, (uv_tcp_t *) client->stream);
- if (uv_accept(server, (uv_stream_t *) client) == 0)
+ if (uv_accept(server, client->stream) == 0)
{
uv_read_start(
- (uv_stream_t *) client,
- sirinet_socket_alloc_buffer,
- sirinet_socket_on_data);
+ client->stream,
+ sirinet_stream_alloc_buffer,
+ sirinet_stream_on_data);
}
else
{
- sirinet_socket_decref(client);
+ sirinet_stream_decref(client);
}
}
}
/* update server flags */
siridb_server_update_flags(server->flags, flags);
- if (server->socket == NULL)
+ if (server->client == NULL)
{
/* connect in case we do not have a connection yet */
siridb_server_connect(siridb, server);
server->flags);
}
-static void on_data(uv_stream_t * client, sirinet_pkg_t * pkg)
+static void on_data(sirinet_stream_t * client, sirinet_pkg_t * pkg)
{
if (Logger.level == LOGGER_DEBUG)
{
- char addr_port[ADDR_BUF_SZ];
- if (sirinet_addr_and_port(addr_port, client) == 0)
+ char * name = sirinet_stream_name(client);
+ if (name != NULL)
{
log_debug(
"Package received from server '%s' "
"(pid: %" PRIu16 ", len: %" PRIu32 ", tp: %s)",
- addr_port,
+ name,
pkg->pid,
pkg->len,
sirinet_bproto_client_str(pkg->tp));
+ free(name);
}
}
}
-static void on_auth_request(uv_stream_t * client, sirinet_pkg_t * pkg)
+static void on_auth_request(sirinet_stream_t * client, sirinet_pkg_t * pkg)
{
bproto_server_t rc;
sirinet_pkg_t * package;
&qp_min_version);
if (rc == BPROTO_AUTH_SUCCESS)
{
- siridb_server_t * server =
- ((sirinet_socket_t * ) client->data)->origin;
- siridb_t * siridb = ((sirinet_socket_t * ) client->data)->siridb;
+ siridb_server_t * server = client->origin;
+ siridb_t * siridb = client->siridb;
/* check and update flags */
BSERVER_flags_update(siridb, server, qp_flags.via.int64);
}
}
-static void on_flags_update(uv_stream_t * client, sirinet_pkg_t * pkg)
+static void on_flags_update(sirinet_stream_t * client, sirinet_pkg_t * pkg)
{
- SERVER_CHECK_AUTHENTICATED(server)
+ SERVER_CHECK_AUTHENTICATED(client, server)
sirinet_pkg_t * package;
- siridb_t * siridb = ((sirinet_socket_t * ) client->data)->siridb;
+ siridb_t * siridb = client->siridb;
qp_unpacker_t unpacker;
qp_unpacker_init(&unpacker, pkg->data, pkg->len);
qp_obj_t qp_flags;
}
}
-static void on_log_level_update(uv_stream_t * client, sirinet_pkg_t * pkg)
+static void on_log_level_update(sirinet_stream_t * client, sirinet_pkg_t * pkg)
{
- SERVER_CHECK_AUTHENTICATED(server)
+ SERVER_CHECK_AUTHENTICATED(client, server)
sirinet_pkg_t * package;
qp_unpacker_t unpacker;
}
}
-static void on_repl_finished(uv_stream_t * client, sirinet_pkg_t * pkg)
+static void on_repl_finished(sirinet_stream_t * client, sirinet_pkg_t * pkg)
{
- SERVER_CHECK_AUTHENTICATED(server)
+ SERVER_CHECK_AUTHENTICATED(client, server)
- siridb_t * siridb = ((sirinet_socket_t * ) client->data)->siridb;
+ siridb_t * siridb = client->siridb;
sirinet_pkg_t * package;
if (siridb->server->flags & SERVER_FLAG_SYNCHRONIZING)
}
}
-static void on_query(uv_stream_t * client, sirinet_pkg_t * pkg, int flags)
+static void on_query(sirinet_stream_t * client, sirinet_pkg_t * pkg, int flags)
{
- SERVER_CHECK_AUTHENTICATED(server)
+ SERVER_CHECK_AUTHENTICATED(client, server)
qp_unpacker_t unpacker;
qp_unpacker_init(&unpacker, pkg->data, pkg->len);
if (flags & SIRIDB_QUERY_FLAG_UPDATE_REPLICA)
{
- siridb_t * siridb = ((sirinet_socket_t * ) client->data)->siridb;
+ siridb_t * siridb = client->siridb;
if (siridb->replica != NULL)
{
pkg->tp = BPROTO_QUERY_SERVER;
}
}
-static void on_insert(uv_stream_t * client, sirinet_pkg_t * pkg, int flags)
+static void on_insert(
+ sirinet_stream_t * client,
+ sirinet_pkg_t * pkg,
+ int flags)
{
- SERVER_CHECK_AUTHENTICATED(server)
+ SERVER_CHECK_AUTHENTICATED(client, server)
sirinet_pkg_t * package;
- siridb_t * siridb = ((sirinet_socket_t * ) client->data)->siridb;
+ siridb_t * siridb = client->siridb;
if ((flags & INSERT_FLAG_POOL) && siridb->replica != NULL)
{
#if DEBUG
}
}
-static void on_register_server(uv_stream_t * client, sirinet_pkg_t * pkg)
+static void on_register_server(sirinet_stream_t * client, sirinet_pkg_t * pkg)
{
- SERVER_CHECK_AUTHENTICATED(server)
+ SERVER_CHECK_AUTHENTICATED(client, server)
sirinet_pkg_t * package;
- siridb_t * siridb = ((sirinet_socket_t * ) client->data)->siridb;
+ siridb_t * siridb = client->siridb;
siridb_server_t * new_server;
if ( siridb->server->flags != SERVER_FLAG_RUNNING ||
}
}
-static void on_drop_series(uv_stream_t * client, sirinet_pkg_t * pkg)
+static void on_drop_series(sirinet_stream_t * client, sirinet_pkg_t * pkg)
{
- SERVER_CHECK_AUTHENTICATED(server)
+ SERVER_CHECK_AUTHENTICATED(client, server)
sirinet_pkg_t * package = NULL;
- siridb_t * siridb = ((sirinet_socket_t * ) client->data)->siridb;
+ siridb_t * siridb = client->siridb;
if ( (~siridb->server->flags & SERVER_FLAG_RUNNING) ||
(siridb->server->flags & SERVER_FLAG_BACKUP_MODE))
}
}
-static void on_req_groups(uv_stream_t * client, sirinet_pkg_t * pkg)
+static void on_req_groups(sirinet_stream_t * client, sirinet_pkg_t * pkg)
{
- SERVER_CHECK_AUTHENTICATED(server)
+ SERVER_CHECK_AUTHENTICATED(client, server)
- siridb_t * siridb = ((sirinet_socket_t * ) client->data)->siridb;
+ siridb_t * siridb = client->siridb;
sirinet_pkg_t * package = siridb_groups_pkg(siridb->groups, pkg->pid);
if (package != NULL)
}
}
-static void on_enable_backup_mode(uv_stream_t * client, sirinet_pkg_t * pkg)
+static void on_enable_backup_mode(
+ sirinet_stream_t * client,
+ sirinet_pkg_t * pkg)
{
- SERVER_CHECK_AUTHENTICATED(server)
+ SERVER_CHECK_AUTHENTICATED(client, server)
- siridb_t * siridb = ((sirinet_socket_t * ) client->data)->siridb;
+ siridb_t * siridb = client->siridb;
sirinet_pkg_t * package;
if ( (~siridb->server->flags & SERVER_FLAG_RUNNING) ||
}
-static void on_disable_backup_mode(uv_stream_t * client, sirinet_pkg_t * pkg)
+static void on_disable_backup_mode(sirinet_stream_t * client, sirinet_pkg_t * pkg)
{
- SERVER_CHECK_AUTHENTICATED(server)
+ SERVER_CHECK_AUTHENTICATED(client, server)
- siridb_t * siridb = ((sirinet_socket_t * ) client->data)->siridb;
+ siridb_t * siridb = client->siridb;
sirinet_pkg_t * package = NULL;
if ( (~siridb->server->flags & SERVER_FLAG_RUNNING) ||
#include <siri/siri.h>
#include <siri/admin/account.h>
#include <siri/admin/request.h>
+#include <siri/db/access.h>
#include <siri/db/auth.h>
#include <siri/db/insert.h>
#include <siri/db/query.h>
#include <siri/db/replicate.h>
+#include <siri/db/server.h>
#include <siri/db/servers.h>
#include <siri/db/users.h>
#include <siri/err.h>
#include <siri/net/clserver.h>
#include <siri/net/promises.h>
#include <siri/net/protocol.h>
+#include <siri/net/tcp.h>
#include <siri/siri.h>
#include <siri/version.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include <siri/db/server.h>
-#include <siri/db/access.h>
const unsigned long int WARNING_PKG_SIZE = RESET_BUF_SIZE;
#define MAX_QUERY_PKG_SIZE 65535
#define DEFAULT_BACKLOG 128
-#define CHECK_SIRIDB(client, siridb) \
-CLIENT_SIRIDB(client, siridb) \
-if ((siridb) == NULL) \
-{ \
- sirinet_pkg_t * package; \
- package = sirinet_pkg_new(pkg->pid, 0, CPROTO_ERR_NOT_AUTHENTICATED, NULL);\
- if (package != NULL) \
- { \
- sirinet_pkg_send((uv_stream_t *) client, package); \
- } \
- return; \
+#define CHECK_SIRIDB(client__, siridb__) \
+siridb_t * siridb__ = (client__)->siridb; \
+if (siridb__ == NULL) \
+{ \
+ sirinet_pkg_t * package; \
+ package = sirinet_pkg_new( \
+ pkg->pid, 0, CPROTO_ERR_NOT_AUTHENTICATED, NULL); \
+ if (package != NULL) \
+ { \
+ sirinet_pkg_send(client, package); \
+ } \
+ return; \
}
static const int SERVER_RUNNING_REINDEXING =
static uv_tcp_t client_server_tcp;
static uv_pipe_t client_server_pipe;
-static void on_data(uv_stream_t * client, sirinet_pkg_t * pkg);
-static void on_tcp_data(uv_stream_t * client, sirinet_pkg_t * pkg);
static void on_tcp_new_connection(uv_stream_t * server, int status);
-static void on_pipe_data(uv_stream_t * client, sirinet_pkg_t * pkg);
-static void on_pipe_free(uv_stream_t * client);
static void on_pipe_new_connection(uv_stream_t * server, int status);
-static void on_auth_request(uv_stream_t * client, sirinet_pkg_t * pkg);
-static void on_query(uv_stream_t * client, sirinet_pkg_t * pkg);
-static void on_insert(uv_stream_t * client, sirinet_pkg_t * pkg);
-static void on_ping(uv_stream_t * client, sirinet_pkg_t * pkg);
-static void on_info(uv_stream_t * client, sirinet_pkg_t * pkg);
-static void on_loaddb(uv_stream_t * client, sirinet_pkg_t * pkg);
+static void on_data(sirinet_stream_t * client, sirinet_pkg_t * pkg);
+static void on_stream_data(sirinet_stream_t * client, sirinet_pkg_t * pkg);
+static void on_auth_request(sirinet_stream_t * client, sirinet_pkg_t * pkg);
+static void on_query(sirinet_stream_t * client, sirinet_pkg_t * pkg);
+static void on_insert(sirinet_stream_t * client, sirinet_pkg_t * pkg);
+static void on_ping(sirinet_stream_t * client, sirinet_pkg_t * pkg);
static void on_reqfile(
- uv_stream_t * client,
+ sirinet_stream_t * client,
sirinet_pkg_t * pkg,
sirinet_clserver_getfile getfile);
-static void on_register_server(uv_stream_t * client, sirinet_pkg_t * pkg);
-static void on_req_admin(uv_stream_t * client, sirinet_pkg_t * pkg);
+static void on_register_server(sirinet_stream_t * client, sirinet_pkg_t * pkg);
+static void on_req_admin(sirinet_stream_t * client, sirinet_pkg_t * pkg);
static void CLSERVER_send_server_error(
siridb_t * siridb,
- uv_stream_t * stream,
+ sirinet_stream_t * client,
sirinet_pkg_t * pkg);
static void CLSERVER_send_pool_error(
- uv_stream_t * stream,
+ sirinet_stream_t * client,
sirinet_pkg_t * pkg);
-static int CLSERVER_on_info_cb(siridb_t * siridb, qp_packer_t * packer);
static void CLSERVER_on_register_server_response(
slist_t * promises,
siridb_server_async_t * server_reg);
log_error("TCP client connection error: %s", uv_strerror(status));
return;
}
- uv_tcp_t * client =
- sirinet_socket_new(SOCKET_CLIENT, (on_data_cb_t) &on_tcp_data);
+ sirinet_stream_t * client = sirinet_stream_new(
+ STREAM_TCP_CLIENT, (on_data_cb_t) &on_stream_data);
if (client != NULL)
{
- uv_tcp_init(loop, client);
+ uv_tcp_init(loop, (uv_tcp_t *) client->stream);
- if (uv_accept(server, (uv_stream_t *) client) == 0)
+ if (uv_accept(server, client->stream) == 0)
{
uv_read_start(
- (uv_stream_t *) client,
- sirinet_socket_alloc_buffer,
- sirinet_socket_on_data);
+ client->stream,
+ sirinet_stream_alloc_buffer,
+ sirinet_stream_on_data);
}
else
{
- sirinet_socket_decref(client);
+ sirinet_stream_decref(client);
}
}
}
log_error("Pipe client connection error: %s", uv_strerror(status));
return;
}
- uv_pipe_t * client =
- sirinet_pipe_new(
- PIPE_CLIENT,
- (on_data_cb_t) &on_pipe_data,
- (on_free_cb_t) &on_pipe_free);
+ sirinet_stream_t * client = sirinet_stream_new(
+ STREAM_PIPE_CLIENT, (on_data_cb_t) &on_stream_data);
if (client != NULL)
{
- uv_pipe_init(loop, client, 0);
+ uv_pipe_init(loop, (uv_pipe_t *) client->stream, 0);
- if (uv_accept(server, (uv_stream_t *) client) == 0)
+ if (uv_accept(server,client->stream) == 0)
{
uv_read_start(
- (uv_stream_t *) client,
- sirinet_pipe_alloc_buffer,
- sirinet_pipe_on_data);
+ client->stream,
+ sirinet_stream_alloc_buffer,
+ sirinet_stream_on_data);
}
else
{
- sirinet_pipe_decref(client);
+ sirinet_stream_decref(client);
}
}
}
-static void on_data(uv_stream_t * client, sirinet_pkg_t * pkg)
+static void on_data(sirinet_stream_t * client, sirinet_pkg_t * pkg)
{
/* in case the online flag is not set, we cannot perform any request */
if (siri.status == SIRI_STATUS_RUNNING)
case CPROTO_REQ_PING:
on_ping(client, pkg);
break;
- case CPROTO_REQ_INFO:
- on_info(client, pkg);
- break;
- case CPROTO_REQ_LOADDB:
- on_loaddb(client, pkg);
- break;
case CPROTO_REQ_REGISTER_SERVER:
on_register_server(client, pkg);
break;
}
else
{
- CLIENT_SIRIDB(client, siridb)
-
/* siridb can be NULL here, make sure we can handle this state */
- CLSERVER_send_server_error(
- siridb,
- client,
- pkg);
+ CLSERVER_send_server_error(client->siridb, client, pkg);
}
}
-static void on_tcp_data(uv_stream_t * client, sirinet_pkg_t * pkg)
+static void on_stream_data(sirinet_stream_t * client, sirinet_pkg_t * pkg)
{
if (Logger.level == LOGGER_DEBUG)
{
- char addr_port[ADDR_BUF_SZ];
- if (sirinet_addr_and_port(addr_port, client) == 0)
+ char * name = sirinet_stream_name(client);
+ if (name != NULL)
{
log_debug(
"Package received from client '%s' "
"(pid: %" PRIu16 ", len: %" PRIu32 ", tp: %s)",
- addr_port,
+ name,
pkg->pid,
pkg->len,
sirinet_cproto_client_str(pkg->tp));
+ free(name);
}
}
else if (pkg->len >= WARNING_PKG_SIZE)
{
- char addr_port[ADDR_BUF_SZ];
- if (sirinet_addr_and_port(addr_port, client) == 0)
+ char * name = sirinet_stream_name(client);
+ if (name != NULL)
{
log_warning(
"Got a large package from '%s' (pid: %d, len: %d, tp: %s)."
" A package size smaller than 1MB is recommended!",
- addr_port,
+ name,
pkg->pid,
pkg->len,
sirinet_cproto_client_str(pkg->tp));
+ free(name);
}
}
on_data(client, pkg);
}
-static void on_pipe_data(uv_stream_t * client, sirinet_pkg_t * pkg)
-{
- if (Logger.level == LOGGER_DEBUG)
- {
- char pipe_name[PIPE_NAME_SZ];
- if (sirinet_pipe_name(pipe_name, client) == 0)
- {
- log_debug(
- "Package received from client '%s' "
- "(pid: %" PRIu16 ", len: %" PRIu32 ", tp: %s)",
- pipe_name,
- pkg->pid,
- pkg->len,
- sirinet_cproto_client_str(pkg->tp));
- }
- }
- else if (pkg->len >= WARNING_PKG_SIZE)
- {
- char pipe_name[PIPE_NAME_SZ];
- if (sirinet_pipe_name(pipe_name, client) == 0)
- {
- log_warning(
- "Got a large package from '%s' (pid: %d, len: %d, tp: %s)."
- " A package size smaller than 1MB is recommended!",
- pipe_name,
- pkg->pid,
- pkg->len,
- sirinet_cproto_client_str(pkg->tp));
- }
- }
-
- on_data(client, pkg);
-}
-
-static void on_pipe_free(uv_stream_t * client)
-{
- char pipe_name[PIPE_NAME_SZ];
- if (sirinet_pipe_name(pipe_name, client) == 0)
- {
- uv_fs_t req;
- uv_fs_unlink(loop, &req, pipe_name, NULL);
- }
-}
-
-static void on_auth_request(uv_stream_t * client, sirinet_pkg_t * pkg)
+static void on_auth_request(sirinet_stream_t * client, sirinet_pkg_t * pkg)
{
cproto_server_t rc;
sirinet_pkg_t * package;
*/
static void CLSERVER_send_server_error(
siridb_t * siridb,
- uv_stream_t * stream,
+ sirinet_stream_t * client,
sirinet_pkg_t * pkg)
{
/* WARNING: siridb can be NULL here */
if (package != NULL)
{
/* ignore result code, signal can be raised */
- sirinet_pkg_send(stream, package);
+ sirinet_pkg_send(client, package);
}
free(err_msg);
}
* A signal is raised in case an allocation error occurred.
*/
static void CLSERVER_send_pool_error(
- uv_stream_t * stream,
+ sirinet_stream_t * client,
sirinet_pkg_t * pkg)
{
log_debug(POOL_ERR_MSG);
if (package != NULL)
{
/* ignore result code, signal can be raised */
- sirinet_pkg_send(stream, package);
+ sirinet_pkg_send(client, package);
}
}
-static void on_query(uv_stream_t * client, sirinet_pkg_t * pkg)
+static void on_query(sirinet_stream_t * client, sirinet_pkg_t * pkg)
{
CHECK_SIRIDB(client, siridb)
if (package != NULL)
{
- sirinet_pkg_send((uv_stream_t *) client, package);
+ sirinet_pkg_send(client, package);
}
return;
}
}
-static void on_insert(uv_stream_t * client, sirinet_pkg_t * pkg)
+static void on_insert(sirinet_stream_t * client, sirinet_pkg_t * pkg)
{
CHECK_SIRIDB(client, siridb)
- CLIENT_USER(client, siridb_user)
char err_msg[SIRIDB_MAX_SIZE_ERR_MSG];
if (!siridb_user_check_access(
- siridb_user,
- SIRIDB_ACCESS_INSERT,
- err_msg))
+ (siridb_user_t *) client->origin,
+ SIRIDB_ACCESS_INSERT,
+ err_msg))
{
log_warning("(%s) %s",
sirinet_cproto_server_str(CPROTO_ERR_USER_ACCESS),
if ( siridb->server->flags != SERVER_FLAG_RUNNING &&
siridb->server->flags != SERVER_RUNNING_REINDEXING)
{
- CLSERVER_send_server_error(siridb, (uv_stream_t *) client, pkg);
+ CLSERVER_send_server_error(siridb, client, pkg);
return;
}
}
}
-static void on_ping(uv_stream_t * client, sirinet_pkg_t * pkg)
+static void on_ping(sirinet_stream_t * client, sirinet_pkg_t * pkg)
{
sirinet_pkg_t * package;
package = sirinet_pkg_new(pkg->pid, 0, CPROTO_RES_ACK, NULL);
}
}
-static void on_info(uv_stream_t * client, sirinet_pkg_t * pkg)
-{
- qp_packer_t * packer = sirinet_packer_new(128);
- if (packer != NULL)
- {
- qp_add_type(packer, QP_ARRAY_OPEN);
- qp_add_string(packer, SIRIDB_VERSION);
- qp_add_type(packer, QP_ARRAY_OPEN);
-
- if (!llist_walk(
- siri.siridb_list,
- (llist_cb) CLSERVER_on_info_cb,
- packer))
- {
- sirinet_pkg_t * package = sirinet_packer2pkg(
- packer,
- pkg->pid,
- CPROTO_RES_INFO);
-
- /* ignore result code, signal can be raised */
- sirinet_pkg_send(client, package);
- }
- else
- {
- qp_packer_free(packer);
- }
- }
-}
-
-/*
- * This function can raise a SIGNAL.
- */
-static void on_loaddb(uv_stream_t * client, sirinet_pkg_t * pkg)
-{
- qp_unpacker_t unpacker;
- qp_unpacker_init(&unpacker, pkg->data, pkg->len);
-
- qp_obj_t qp_dbpath;
- if (qp_next(&unpacker, &qp_dbpath) == QP_RAW)
- {
- char * dbpath = strndup(
- (const char *) qp_dbpath.via.raw, qp_dbpath.len);
-
- if (dbpath == NULL)
- {
- ERR_ALLOC
- }
- else
- {
- siridb_t * siridb = siridb_new(dbpath, LOCK_QUIT_IF_EXIST);
- if (siridb != NULL)
- {
- siridb->server->flags |= SERVER_FLAG_RUNNING;
-
- /* Force one heart-beat */
- siri_heartbeat_force();
- }
- sirinet_pkg_t * package = sirinet_pkg_new(
- pkg->pid,
- 0,
- (siridb == NULL) ?
- CPROTO_ERR_LOADING_DB : CPROTO_RES_ACK,
- NULL);
- if (package != NULL)
- {
- sirinet_pkg_send(client, package);
- }
- free(dbpath);
- }
- }
- else
- {
- log_error("Incorrect package received: 'on_loaddb'");
- }
-}
-
/*
* This function can raise a SIGNAL.
*/
static void on_reqfile(
- uv_stream_t * client,
+ sirinet_stream_t * client,
sirinet_pkg_t * pkg,
sirinet_clserver_getfile getfile)
{
CHECK_SIRIDB(client, siridb)
- CLIENT_USER(client, siridb_user)
-
+ siridb_user_t * user = client->origin;
sirinet_pkg_t * package = NULL;
char err_msg[SIRIDB_MAX_SIZE_ERR_MSG];
err_msg);
}
else if (!siridb_user_check_access(
- siridb_user,
+ user,
SIRIDB_ACCESS_PROFILE_FULL,
err_msg))
{
/*
* This function can raise a SIGNAL.
*/
-static void on_register_server(uv_stream_t * client, sirinet_pkg_t * pkg)
+static void on_register_server(sirinet_stream_t * client, sirinet_pkg_t * pkg)
{
CHECK_SIRIDB(client, siridb)
- CLIENT_USER(client, siridb_user)
+ siridb_user_t * user = client->origin;
sirinet_pkg_t * package = NULL;
siridb_server_t * new_server = NULL;
err_msg);
}
else if (!siridb_user_check_access(
- siridb_user,
+ user,
SIRIDB_ACCESS_PROFILE_FULL,
err_msg))
{
if (servers != NULL && (package = sirinet_pkg_dup(pkg)) != NULL)
{
/* make sure to decrement the client in the callback */
- sirinet_client_incref(client);
+ sirinet_stream_incref(client);
siridb_servers_send_pkg(
servers,
slist_free(servers);
}
-static void on_req_admin(uv_stream_t * client, sirinet_pkg_t * pkg)
+static void on_req_admin(sirinet_stream_t * client, sirinet_pkg_t * pkg)
{
qp_unpacker_t unpacker;
qp_packer_t * packer = NULL;
}
}
-/*
- * Typedef: llist_cb
- * Returns 0 if successful or -1 and a SIGNAL is raised if not.
- */
-static int CLSERVER_on_info_cb(siridb_t * siridb, qp_packer_t * packer)
-{
- return qp_add_string(packer, siridb->dbname);
-}
-
/*
* Typedef: sirinet_promises_cb
*/
}
/* decref the client */
- sirinet_client_decref(server_reg->client);
+ sirinet_stream_decref(server_reg->client);
/* free server register object */
free(server_reg);
#include <assert.h>
-#include <logger/logger.h>
-#include <siri/admin/client.h>
-#include <siri/err.h>
-#include <siri/net/protocol.h>
-#include <siri/net/pipe.h>
-#include <siri/siri.h>
-#include <stdlib.h>
#include <string.h>
+#include <stdlib.h>
+#include <siri/net/pipe.h>
+#include <xpath/xpath.h>
-#define MAX_ALLOWED_PKG_SIZE 20971520 /* 20 MB */
-
-#define QUIT_PIPE \
- free(spipe->buf); \
- spipe->buf = NULL; \
- spipe->len = 0; \
- spipe->size = 0; \
- spipe->on_data = NULL; \
- sirinet_pipe_decref(client); \
- return;
-
-/*
- * This function can raise a SIGNAL.
- */
-void sirinet_pipe_alloc_buffer(
- uv_handle_t * handle,
- size_t suggested_size,
- uv_buf_t * buf)
-{
- sirinet_pipe_t * spipe = (sirinet_pipe_t *) handle->data;
-
- if (!spipe->len && spipe->size > RESET_BUF_SIZE)
- {
- free(spipe->buf);
- spipe->buf = (char *) malloc(suggested_size);
- if (spipe->buf == NULL)
- {
- ERR_ALLOC
- buf->len = 0;
- return;
- }
- spipe->size = suggested_size;
- spipe->len = 0;
- }
- buf->base = spipe->buf + spipe->len;
- buf->len = spipe->size - spipe->len;
-}
-
-/*
- * Buffer should have a size of PIPE_NAME_SZ
- *
- * Return 0 if successful or -1 in case of an error.
- */
-int sirinet_pipe_name(char * buffer, uv_stream_t * client)
-{
- size_t len = PIPE_NAME_SZ - 1;
-
- if (uv_pipe_getsockname(
- (uv_pipe_t *) client,
- buffer,
- &len))
- {
- return -1;
- }
-
- buffer[len] = 0;
- return 0;
-}
-
-/*
- * This function can raise a SIGNAL.
- */
-void sirinet_pipe_on_data(
- uv_stream_t * client,
- ssize_t nread,
- const uv_buf_t * buf)
-{
- sirinet_pipe_t * spipe = (sirinet_pipe_t *) client->data;
- sirinet_pkg_t * pkg;
- size_t total_sz;
- uint8_t check;
-
- /*
- * spipe->on_data is NULL when 'sirinet_pipe_decref' is called from
- * within this function. We should never call 'sirinet_pipe_decref' twice
- * so the best thing is to log and and exit this function.
- */
- if (spipe->on_data == NULL)
- {
- char pipe_name[PIPE_NAME_SZ];
- if (sirinet_pipe_name(pipe_name, client) == 0)
- {
- log_error(
- "Received data from '%s' but we ignore the data since the "
- "connection will be closed in a few seconds...",
- pipe_name);
- }
- return;
- }
-
- if (nread < 0)
- {
- if (nread != UV_EOF)
- {
- log_error("Read error: %s", uv_err_name(nread));
- }
- QUIT_PIPE
- }
-
- spipe->len += nread;
-
- if (spipe->len < sizeof(sirinet_pkg_t))
- {
- return;
- }
-
- pkg = (sirinet_pkg_t *) spipe->buf;
- check = pkg->tp ^ 255;
- if ( check != pkg->checkbit ||
- (spipe->tp == PIPE_CLIENT && pkg->len > MAX_ALLOWED_PKG_SIZE))
- {
- char pipe_name[PIPE_NAME_SZ];
- if (sirinet_pipe_name(pipe_name, client) == 0)
- {
- log_error(
- "Got an illegal package or size too large from '%s', "
- "closing connection "
- "(pid: %" PRIu16 ", len: %" PRIu32 ", tp: %" PRIu8 ")",
- pipe_name, pkg->pid, pkg->len, pkg->tp);
- }
- QUIT_PIPE
- }
-
- total_sz = sizeof(sirinet_pkg_t) + pkg->len;
- if (spipe->len < total_sz)
- {
- if (spipe->size < total_sz)
- {
- char * tmp = realloc(spipe->buf, total_sz);
- if (tmp == NULL)
- {
- log_critical(
- "Cannot allocate size for package "
- "(pid: %" PRIu16 ", len: %" PRIu32 ", tp: %" PRIu8 ")",
- pkg->pid, pkg->len, pkg->tp);
- QUIT_PIPE
- }
- spipe->buf = tmp;
- spipe->size = total_sz;
- }
- return;
- }
-
- /* call on-data function */
- (*spipe->on_data)(client, pkg);
-
- spipe->len -= total_sz;
-
- if (spipe->len > 0)
- {
- /* move data and call sirinet_pipe_on_data() function again */
- memmove(spipe->buf, spipe->buf + total_sz, spipe->len);
- sirinet_pipe_on_data(client, 0, buf);
- }
-}
+#define PIPE_NAME_BUF_SZ SIRI_PATH_MAX
/*
- * Returns NULL and raises a SIGNAL in case an error has occurred.
+ * Return a name for the connection if successful or NULL in case of a failure.
*
- * Note: ((sirinet_pipe_t *) pipe->data)->ref is initially set to 1
+ * The returned value is malloced and should be freed.
*/
-uv_pipe_t * sirinet_pipe_new(
- sirinet_pipe_tp_t tp,
- on_data_cb_t cb_data,
- on_free_cb_t cb_free)
+char * sirinet_pipe_name(uv_pipe_t * client)
{
- sirinet_pipe_t * spipe =
- (sirinet_pipe_t *) malloc(sizeof(sirinet_pipe_t));
+ size_t len = PIPE_NAME_BUF_SZ - 1;
+ char * buffer = malloc(PIPE_NAME_BUF_SZ);
- if (spipe == NULL)
+ if (buffer == NULL || uv_pipe_getsockname(client, buffer, &len))
{
- ERR_ALLOC
+ free(buffer);
return NULL;
}
- spipe->tp = tp;
- spipe->on_data = cb_data;
- spipe->on_free = cb_free;
- spipe->buf = NULL;
- spipe->len = 0;
- spipe->size = -1; /* this will force allocating on first request */
- spipe->origin = NULL;
- spipe->siridb = NULL;
- spipe->ref = 1;
- spipe->pipe.data = spipe;
-
- return &spipe->pipe;
-}
-
-/*
- * Never use this function but call sirinet_pipe_decref.
- * Destroy pipe. (parsing NULL is not allowed)
- *
- * We know three different pipe types:
- * - client: used for clients. a user object might be destroyed.
- * - back-end: used to connect to other servers. a server might be destroyed.
- * - server: user for severs connecting to here. a server might be destroyed.
- *
- * In case a server is destroyed, remaining promises will be cancelled and
- * the call-back functions will be called.
- */
-void sirinet__pipe_free(uv_stream_t * client)
-{
- sirinet_pipe_t * spipe = client->data;
-
-#if DEBUG
- log_debug("Free pipe type: %d", spipe->tp);
-#endif
-
- switch (spipe->tp)
- {
- case PIPE_CLIENT: /* listens to client connections */
- if (spipe->origin != NULL)
- {
- siridb_user_t * user = (siridb_user_t *) spipe->origin;
- siridb_user_decref(user);
- }
- break;
- case PIPE_BACKEND: /* listens to server connections */
- if (spipe->origin != NULL)
- {
- siridb_server_t * server = (siridb_server_t *) spipe->origin;
- siridb_server_decref(server);
- }
- break;
- }
-
- if (spipe->on_free != NULL)
- {
- spipe->on_free(client);
- }
+ buffer[len] = '\0';
+ return buffer;
- free(spipe->buf);
- free(spipe);
}
typedef struct pkg_send_s
{
sirinet_pkg_t * pkg;
- uv_stream_t * client;
+ sirinet_stream_t * client;
} pkg_send_t;
static void PKG_write_cb(uv_write_t * req, int status);
*
* Note: pkg will be freed after calling this function.
*/
-int sirinet_pkg_send(uv_stream_t * client, sirinet_pkg_t * pkg)
+int sirinet_pkg_send(sirinet_stream_t * client, sirinet_pkg_t * pkg)
{
uv_write_t * req = (uv_write_t *) malloc(sizeof(uv_write_t));
}
/* increment client reference counter */
- sirinet_client_incref(client);
+ sirinet_stream_incref(client);
data->client = client;
data->pkg = pkg;
(char *) pkg,
sizeof(sirinet_pkg_t) + pkg->len);
- uv_write(req, client, &wrbuf, 1, PKG_write_cb);
+ uv_write(req, client->stream, &wrbuf, 1, PKG_write_cb);
return 0;
}
pkg_send_t * data = (pkg_send_t *) req->data;
- sirinet_client_decref(data->client);
+ sirinet_stream_decref(data->client);
free(data->pkg);
free(data);
case CPROTO_REQ_INSERT: return "CPROTO_REQ_INSERT";
case CPROTO_REQ_AUTH: return "CPROTO_REQ_AUTH";
case CPROTO_REQ_PING: return "CPROTO_REQ_PING";
- case CPROTO_REQ_INFO: return "CPROTO_REQ_INFO";
/* deprecated, used by the old SiriDB manage tool */
- case CPROTO_REQ_LOADDB: return "CPROTO_REQ_LOADDB";
case CPROTO_REQ_REGISTER_SERVER: return "CPROTO_REQ_REGISTER_SERVER";
case CPROTO_REQ_FILE_SERVERS: return "CPROTO_REQ_FILE_SERVERS";
case CPROTO_REQ_FILE_USERS: return "CPROTO_REQ_FILE_USERS";
case CPROTO_RES_INSERT: return "CPROTO_RES_INSERT";
case CPROTO_RES_AUTH_SUCCESS: return "CPROTO_RES_AUTH_SUCCESS";
case CPROTO_RES_ACK: return "CPROTO_RES_ACK";
-
- /* deprecated, used by the old SiriDB manage tool */
- case CPROTO_RES_INFO: return "CPROTO_RES_INFO";
case CPROTO_RES_FILE: return "CPROTO_RES_FILE";
- /* end deprecated */
case CPROTO_ACK_ADMIN: return "CPROTO_ACK_ADMIN";
case CPROTO_ACK_ADMIN_DATA: return "CPROTO_ACK_ADMIN_DATA";
+
case CPROTO_ERR_MSG: return "CPROTO_ERR_MSG";
case CPROTO_ERR_QUERY: return "CPROTO_ERR_QUERY";
case CPROTO_ERR_INSERT: return "CPROTO_ERR_INSERT";
case CPROTO_ERR_AUTH_CREDENTIALS: return "CPROTO_ERR_AUTH_CREDENTIALS";
case CPROTO_ERR_AUTH_UNKNOWN_DB: return "CPROTO_ERR_AUTH_UNKNOWN_DB";
- /* deprecated, used by the old SiriDB manage tool */
- case CPROTO_ERR_LOADING_DB: return "CPROTO_ERR_LOADING_DB";
case CPROTO_ERR_FILE: return "CPROTO_ERR_FILE";
- /* end deprecated */
-
case CPROTO_ERR_ADMIN: return "CPROTO_ERR_ADMIN";
case CPROTO_ERR_ADMIN_INVALID_REQUEST: return "CPROTO_ERR_ADMIN_INVALID_REQUEST";
default:
+++ /dev/null
-/*
- * socket.c - Handle TCP request.
- *
- * author : Jeroen van der Heijden
- * email : jeroen@transceptor.technology
- * copyright : 2016, Transceptor Technology
- *
- * changes
- * - initial version, 09-03-2016
- *
- */
-#include <assert.h>
-#include <logger/logger.h>
-#include <siri/admin/client.h>
-#include <siri/err.h>
-#include <siri/net/protocol.h>
-#include <siri/net/socket.h>
-#include <siri/siri.h>
-#include <stdlib.h>
-#include <string.h>
-
-#define MAX_ALLOWED_PKG_SIZE 20971520 /* 20 MB */
-
-#define QUIT_SOCKET \
- free(ssocket->buf); \
- ssocket->buf = NULL; \
- ssocket->len = 0; \
- ssocket->size = 0; \
- ssocket->on_data = NULL; \
- sirinet_socket_decref(client); \
- return;
-
-/* dns_req_family_map maps to IP_SUPPORT values defined in socket.h */
-int dns_req_family_map[3] = {AF_UNSPEC, AF_INET, AF_INET6};
-
-const char * sirinet_socket_ip_support_str(uint8_t ip_support)
-{
- switch (ip_support)
- {
- case IP_SUPPORT_ALL: return "ALL";
- case IP_SUPPORT_IPV4ONLY: return "IPV4ONLY";
- case IP_SUPPORT_IPV6ONLY: return "IPV6ONLY";
- default: return "UNKNOWN";
- }
-}
-
-/*
- * This function can raise a SIGNAL.
- */
-void sirinet_socket_alloc_buffer(
- uv_handle_t * handle,
- size_t suggested_size,
- uv_buf_t * buf)
-{
- sirinet_socket_t * ssocket = (sirinet_socket_t *) handle->data;
-
- if (!ssocket->len && ssocket->size > RESET_BUF_SIZE)
- {
- free(ssocket->buf);
- ssocket->buf = (char *) malloc(suggested_size);
- if (ssocket->buf == NULL)
- {
- ERR_ALLOC
- buf->len = 0;
- return;
- }
- ssocket->size = suggested_size;
- ssocket->len = 0;
- }
- buf->base = ssocket->buf + ssocket->len;
- buf->len = ssocket->size - ssocket->len;
-}
-
-/*
- * Buffer should have a size of ADDR_BUF_SZ
- *
- * Return 0 if successful or -1 in case of an error.
- */
-int sirinet_addr_and_port(char * buffer, uv_stream_t * client)
-{
- struct sockaddr_storage name;
- int namelen = sizeof(name);
-
- if (uv_tcp_getpeername(
- (uv_tcp_t *) client,
- (struct sockaddr *) &name,
- &namelen))
- {
- return -1;
- }
-
- switch (name.ss_family)
- {
- case AF_INET:
- {
- char addr[INET_ADDRSTRLEN];
- uv_inet_ntop(
- AF_INET,
- &((struct sockaddr_in *) &name)->sin_addr,
- addr,
- sizeof(addr));
- snprintf(
- buffer,
- ADDR_BUF_SZ,
- "%s:%d",
- addr,
- ntohs(((struct sockaddr_in *) &name)->sin_port));
- }
- break;
-
- case AF_INET6:
- {
- char addr[INET6_ADDRSTRLEN];
- uv_inet_ntop(
- AF_INET6,
- &((struct sockaddr_in6 *) &name)->sin6_addr,
- addr,
- sizeof(addr));
- snprintf(
- buffer,
- ADDR_BUF_SZ,
- "[%s]:%d",
- addr,
- ntohs(((struct sockaddr_in6 *) &name)->sin6_port));
- }
- break;
-
- default:
- return -1;
- }
-
- return 0;
-}
-
-/*
- * This function can raise a SIGNAL.
- */
-void sirinet_socket_on_data(
- uv_stream_t * client,
- ssize_t nread,
- const uv_buf_t * buf)
-{
- sirinet_socket_t * ssocket = (sirinet_socket_t *) client->data;
- sirinet_pkg_t * pkg;
- size_t total_sz;
- uint8_t check;
-
- /*
- * ssocket->on_data is NULL when 'sirinet_socket_decref' is called from
- * within this function. We should never call 'sirinet_socket_decref' twice
- * so the best thing is to log and and exit this function.
- */
- if (ssocket->on_data == NULL)
- {
- char addr_port[ADDR_BUF_SZ];
- if (sirinet_addr_and_port(addr_port, client) == 0)
- {
- log_error(
- "Received data from '%s' but we ignore the data since the "
- "connection will be closed in a few seconds...",
- addr_port);
- }
- return;
- }
-
- if (nread < 0)
- {
- if (nread != UV_EOF)
- {
- log_error("Read error: %s", uv_err_name(nread));
- }
- QUIT_SOCKET
- }
-
- ssocket->len += nread;
-
- if (ssocket->len < sizeof(sirinet_pkg_t))
- {
- return;
- }
-
- pkg = (sirinet_pkg_t *) ssocket->buf;
- check = pkg->tp ^ 255;
- if ( check != pkg->checkbit ||
- (ssocket->tp == SOCKET_CLIENT && pkg->len > MAX_ALLOWED_PKG_SIZE))
- {
- char addr_port[ADDR_BUF_SZ];
- if (sirinet_addr_and_port(addr_port, client) == 0)
- {
- log_error(
- "Got an illegal package or size too large from '%s', "
- "closing connection "
- "(pid: %" PRIu16 ", len: %" PRIu32 ", tp: %" PRIu8 ")",
- addr_port, pkg->pid, pkg->len, pkg->tp);
- }
- QUIT_SOCKET
- }
-
- total_sz = sizeof(sirinet_pkg_t) + pkg->len;
- if (ssocket->len < total_sz)
- {
- if (ssocket->size < total_sz)
- {
- char * tmp = realloc(ssocket->buf, total_sz);
- if (tmp == NULL)
- {
- log_critical(
- "Cannot allocate size for package "
- "(pid: %" PRIu16 ", len: %" PRIu32 ", tp: %" PRIu8 ")",
- pkg->pid, pkg->len, pkg->tp);
- QUIT_SOCKET
- }
- ssocket->buf = tmp;
- ssocket->size = total_sz;
- }
- return;
- }
-
- /* call on-data function */
- (*ssocket->on_data)(client, pkg);
-
- ssocket->len -= total_sz;
-
- if (ssocket->len > 0)
- {
- /* move data and call sirinet_socket_on_data() function again */
- memmove(ssocket->buf, ssocket->buf + total_sz, ssocket->len);
- sirinet_socket_on_data(client, 0, buf);
- }
-}
-
-/*
- * Returns NULL and raises a SIGNAL in case an error has occurred.
- *
- * Note: ((sirinet_socket_t *) socket->data)->ref is initially set to 1
- */
-uv_tcp_t * sirinet_socket_new(sirinet_socket_tp_t tp, on_data_cb_t cb)
-{
- sirinet_socket_t * ssocket =
- (sirinet_socket_t *) malloc(sizeof(sirinet_socket_t));
-
- if (ssocket == NULL)
- {
- ERR_ALLOC
- return NULL;
- }
-
- ssocket->tp = tp;
- ssocket->on_data = cb;
- ssocket->buf = NULL;
- ssocket->len = 0;
- ssocket->size = -1; /* this will force allocating on first request */
- ssocket->origin = NULL;
- ssocket->siridb = NULL;
- ssocket->ref = 1;
- ssocket->tcp.data = ssocket;
-
- return &ssocket->tcp;
-}
-
-/*
- * Never use this function but call sirinet_socket_decref.
- * Destroy socket. (parsing NULL is not allowed)
- *
- * We know three different socket types:
- * - client: used for clients. a user object might be destroyed.
- * - back-end: used to connect to other servers. a server might be destroyed.
- * - server: user for severs connecting to here. a server might be destroyed.
- *
- * In case a server is destroyed, remaining promises will be cancelled and
- * the call-back functions will be called.
- */
-void sirinet__socket_free(uv_stream_t * client)
-{
- sirinet_socket_t * ssocket = client->data;
-
-#if DEBUG
- log_debug("Free socket type: %d", ssocket->tp);
-#endif
-
- switch (ssocket->tp)
- {
- case SOCKET_CLIENT: /* listens to client connections */
- if (ssocket->origin != NULL)
- {
- siridb_user_t * user = (siridb_user_t *) ssocket->origin;
- siridb_user_decref(user);
- }
- break;
- case SOCKET_BACKEND: /* listens to server connections */
- if (ssocket->origin != NULL)
- {
- siridb_server_t * server = (siridb_server_t *) ssocket->origin;
- siridb_server_decref(server);
- }
- break;
- case SOCKET_SERVER: /* a server connection */
- {
- siridb_server_t * server = (siridb_server_t *) ssocket->origin;
- server->socket = NULL;
- server->flags = 0;
- siridb_server_decref(server);
- }
- break;
- case SOCKET_MANAGE: /* a server manage connection */
- siri_admin_client_free((siri_admin_client_t *) ssocket->origin);
- siri.socket = NULL;
- break;
- }
- free(ssocket->buf);
- free(ssocket);
-}
-
-
-
-
-
--- /dev/null
+/*
+ * stream.c - Handle Stream request.
+ *
+ * author : Jeroen van der Heijden
+ * email : jeroen@transceptor.technology
+ * copyright : 2016, Transceptor Technology
+ *
+ * changes
+ * - initial version, 09-03-2016
+ *
+ */
+#include <assert.h>
+#include <logger/logger.h>
+#include <siri/admin/client.h>
+#include <siri/err.h>
+#include <siri/net/protocol.h>
+#include <siri/net/stream.h>
+#include <siri/net/pipe.h>
+#include <siri/net/tcp.h>
+#include <siri/siri.h>
+#include <stdlib.h>
+#include <string.h>
+#include <siri/siri.h>
+
+#define MAX_ALLOWED_PKG_SIZE 20971520 /* 20 MB */
+
+#define QUIT_STREAM \
+ free(client->buf); \
+ client->buf = NULL; \
+ client->len = 0; \
+ client->size = 0; \
+ client->on_data = NULL; \
+ sirinet_stream_decref(client); \
+ return;
+
+
+/*
+ * Returns NULL and raises a SIGNAL in case an error has occurred.
+ *
+ * Note: object->ref is initially set to 1
+ */
+sirinet_stream_t * sirinet_stream_new(sirinet_stream_tp_t tp, on_data_cb_t cb)
+{
+ sirinet_stream_t * client = malloc(sizeof(sirinet_stream_t));
+
+ if (client == NULL)
+ {
+ ERR_ALLOC
+ return NULL;
+ }
+
+ client->tp = tp;
+ client->on_data = cb;
+ client->buf = NULL;
+ client->len = 0;
+ client->size = -1; /* this will force allocating on first request */
+ client->origin = NULL;
+ client->siridb = NULL;
+ client->ref = 1;
+
+ size_t stream_sz = (tp == STREAM_PIPE_CLIENT)
+ ? sizeof(uv_pipe_t)
+ : sizeof(uv_tcp_t);
+
+ client->stream = malloc(stream_sz);
+ if (client->stream == NULL)
+ {
+ free(client);
+ ERR_ALLOC
+ return NULL;
+ }
+
+ client->stream->data = client;
+
+ return client;
+}
+
+/*
+ * Return a name for the connection if successful or NULL in case of a failure.
+ *
+ * The returned value is malloced and should be freed.
+ */
+char * sirinet_stream_name(sirinet_stream_t * client)
+{
+ switch (client->tp)
+ {
+ case STREAM_TCP_CLIENT:
+ case STREAM_TCP_BACKEND:
+ case STREAM_TCP_SERVER:
+ case STREAM_TCP_MANAGE:
+ return sirinet_pipe_name((uv_pipe_t *) client->stream);
+ case STREAM_PIPE_CLIENT:
+ return sirinet_tcp_name((uv_tcp_t *) client->stream);
+ }
+ return NULL;
+}
+
+
+/*
+ * This function can raise a SIGNAL.
+ */
+void sirinet_stream_alloc_buffer(
+ uv_handle_t * handle,
+ size_t suggested_size,
+ uv_buf_t * buf)
+{
+ sirinet_stream_t * client = (sirinet_stream_t *) handle->data;
+
+ if (!client->len && client->size > RESET_BUF_SIZE)
+ {
+ free(client->buf);
+ client->buf = (char *) malloc(suggested_size);
+ if (client->buf == NULL)
+ {
+ ERR_ALLOC
+ buf->len = 0;
+ return;
+ }
+ client->size = suggested_size;
+ client->len = 0;
+ }
+ buf->base = client->buf + client->len;
+ buf->len = client->size - client->len;
+}
+
+/*
+ * This function can raise a SIGNAL.
+ */
+void sirinet_stream_on_data(
+ uv_stream_t * uvclient,
+ ssize_t nread,
+ const uv_buf_t * buf)
+{
+ sirinet_stream_t * client = uvclient->data;
+ sirinet_pkg_t * pkg;
+ size_t total_sz;
+ uint8_t check;
+
+ /*
+ * client->on_data is NULL when 'sirinet_stream_decref' is called from
+ * within this function. We should never call 'sirinet_stream_decref' twice
+ * so the best thing is to log and and exit this function.
+ */
+ if (client->on_data == NULL)
+ {
+ char * name = sirinet_stream_name(client);
+ if (name != NULL)
+ {
+ log_error(
+ "Received data from '%s' but we ignore the data since the "
+ "connection will be closed in a few seconds...",
+ name);
+ free(name);
+ }
+ return;
+ }
+
+ if (nread < 0)
+ {
+ if (nread != UV_EOF)
+ {
+ log_error("Read error: %s", uv_err_name(nread));
+ }
+ QUIT_STREAM
+ }
+
+ client->len += nread;
+
+ if (client->len < sizeof(sirinet_pkg_t))
+ {
+ return;
+ }
+
+ pkg = (sirinet_pkg_t *) client->buf;
+ check = pkg->tp ^ 255;
+ if (check != pkg->checkbit ||
+ (( client->tp == STREAM_TCP_CLIENT ||
+ client->tp == STREAM_PIPE_CLIENT) &&
+ pkg->len > MAX_ALLOWED_PKG_SIZE))
+ {
+ char * name = sirinet_stream_name(client);
+ if (name != NULL)
+ {
+ log_error(
+ "Got an illegal package or size too large from '%s', "
+ "closing connection "
+ "(pid: %" PRIu16 ", len: %" PRIu32 ", tp: %" PRIu8 ")",
+ name, pkg->pid, pkg->len, pkg->tp);
+ free(name);
+ }
+ QUIT_STREAM
+ }
+
+ total_sz = sizeof(sirinet_pkg_t) + pkg->len;
+ if (client->len < total_sz)
+ {
+ if (client->size < total_sz)
+ {
+ char * tmp = realloc(client->buf, total_sz);
+ if (tmp == NULL)
+ {
+ log_critical(
+ "Cannot allocate size for package "
+ "(pid: %" PRIu16 ", len: %" PRIu32 ", tp: %" PRIu8 ")",
+ pkg->pid, pkg->len, pkg->tp);
+ QUIT_STREAM
+ }
+ client->buf = tmp;
+ client->size = total_sz;
+ }
+ return;
+ }
+
+ /* call on-data function */
+ (*client->on_data)(client, pkg);
+
+ client->len -= total_sz;
+
+ if (client->len > 0)
+ {
+ /* move data and call sirinet_stream_on_data() function again */
+ memmove(client->buf, client->buf + total_sz, client->len);
+ sirinet_stream_on_data(uvclient, 0, buf);
+ }
+}
+
+
+
+/*
+ * Never use this function but call sirinet_stream_decref.
+ * Destroy stream. (parsing NULL is not allowed)
+ *
+ * We know three different stream types:
+ * - client: used for clients. a user object might be destroyed.
+ * - back-end: used to connect to other servers. a server might be destroyed.
+ * - server: user for severs connecting to here. a server might be destroyed.
+ *
+ * In case a server is destroyed, remaining promises will be cancelled and
+ * the call-back functions will be called.
+ */
+void sirinet__stream_free(uv_stream_t * uvclient)
+{
+ sirinet_stream_t * client = uvclient->data;
+
+#if DEBUG
+ log_debug("Free socket client type: %d", client->tp);
+#endif
+
+ switch (client->tp)
+ {
+ case STREAM_TCP_CLIENT: /* listens to client connections */
+ if (client->origin != NULL)
+ {
+ siridb_user_t * user = client->origin;
+ siridb_user_decref(user);
+ }
+ break;
+ case STREAM_TCP_BACKEND: /* listens to server connections */
+ if (client->origin != NULL)
+ {
+ siridb_server_t * server = (siridb_server_t *) client->origin;
+ siridb_server_decref(server);
+ }
+ break;
+ case STREAM_TCP_SERVER: /* a server connection */
+ {
+ siridb_server_t * server = client->origin;
+ server->client = NULL;
+ server->flags = 0;
+ siridb_server_decref(server);
+ }
+ break;
+ case STREAM_TCP_MANAGE: /* a server manage connection */
+ siri_admin_client_free((siri_admin_client_t *) client->origin);
+ siri.client = NULL;
+ break;
+ case STREAM_PIPE_CLIENT:
+ {
+ char * pipe_name = sirinet_pipe_name((uv_pipe_t *) uvclient);
+ if (pipe_name != NULL)
+ {
+ uv_fs_t * req = malloc(sizeof(uv_fs_t));
+ if (req != NULL)
+ {
+ uv_fs_unlink(siri.loop, req, pipe_name, (uv_fs_cb) free);
+ }
+ free(pipe_name);
+ }
+ }
+
+ }
+ free(client->buf);
+ free(client);
+ free(uvclient);
+}
+
+
+
+
+
+
--- /dev/null
+/*
+ * tcp.c - Handle TCP request.
+ *
+ * author : Jeroen van der Heijden
+ * email : jeroen@transceptor.technology
+ * copyright : 2016, Transceptor Technology
+ *
+ * changes
+ * - initial version, 09-03-2016
+ *
+ */
+#include <siri/net/tcp.h>
+#include <stdlib.h>
+#include <string.h>
+#include <uv.h>
+
+#define TCP_NAME_BUF_SZ 54
+
+/* dns_req_family_map maps to IP_SUPPORT values defined in socket.h */
+int dns_req_family_map[3] = {AF_UNSPEC, AF_INET, AF_INET6};
+
+const char * sirinet_tcp_ip_support_str(uint8_t ip_support)
+{
+ switch (ip_support)
+ {
+ case IP_SUPPORT_ALL: return "ALL";
+ case IP_SUPPORT_IPV4ONLY: return "IPV4ONLY";
+ case IP_SUPPORT_IPV6ONLY: return "IPV6ONLY";
+ default: return "UNKNOWN";
+ }
+}
+
+/*
+ * Return a name for the connection if successful or NULL in case of a failure.
+ *
+ * The returned value is malloced and should be freed.
+ */
+char * sirinet_tcp_name(uv_tcp_t * client)
+{
+ char * buffer = malloc(TCP_NAME_BUF_SZ);
+ struct sockaddr_storage name;
+ int namelen = sizeof(name);
+
+ if (buffer == NULL ||
+ uv_tcp_getpeername(client, (struct sockaddr *) &name, &namelen))
+ {
+ goto failed;
+ }
+
+ switch (name.ss_family)
+ {
+ case AF_INET:
+ {
+ char addr[INET_ADDRSTRLEN];
+ uv_inet_ntop(
+ AF_INET,
+ &((struct sockaddr_in *) &name)->sin_addr,
+ addr,
+ sizeof(addr));
+ snprintf(
+ buffer,
+ TCP_NAME_BUF_SZ,
+ "%s:%d",
+ addr,
+ ntohs(((struct sockaddr_in *) &name)->sin_port));
+ }
+ break;
+
+ case AF_INET6:
+ {
+ char addr[INET6_ADDRSTRLEN];
+ uv_inet_ntop(
+ AF_INET6,
+ &((struct sockaddr_in6 *) &name)->sin6_addr,
+ addr,
+ sizeof(addr));
+ snprintf(
+ buffer,
+ TCP_NAME_BUF_SZ,
+ "[%s]:%d",
+ addr,
+ ntohs(((struct sockaddr_in6 *) &name)->sin6_port));
+ }
+ break;
+
+ default:
+ goto failed;
+ }
+
+ return buffer;
+
+failed:
+ free(buffer);
+ return NULL;
+}
+
+
+
+
+
+++ /dev/null
-/*
- * listener.c - contains functions for processing queries.
- *
- * author : Jeroen van der Heijden
- * email : jeroen@transceptor.technology
- * copyright : 2016, Transceptor Technology
- *
- * changes
- * - initial version, 10-03-2016
- *
- */
-#include <assert.h>
-#include <cexpr/cexpr.h>
-#include <inttypes.h>
-#include <logger/logger.h>
-#include <qpack/qpack.h>
-#include <siri/async.h>
-#include <siri/db/aggregate.h>
-#include <siri/db/group.h>
-#include <siri/db/groups.h>
-#include <siri/db/nodes.h>
-#include <siri/db/presuf.h>
-#include <siri/db/props.h>
-#include <siri/db/props.h>
-#include <siri/db/query.h>
-#include <siri/db/re.h>
-#include <siri/db/series.h>
-#include <siri/db/server.h>
-#include <siri/db/servers.h>
-#include <siri/db/shard.h>
-#include <siri/db/user.h>
-#include <siri/db/users.h>
-#include <siri/err.h>
-#include <siri/grammar/gramp.h>
-#include <siri/help/help.h>
-#include <siri/net/promises.h>
-#include <siri/net/protocol.h>
-#include <siri/net/clserver.h>
-#include <siri/parser/listener.h>
-#include <siri/parser/queries.h>
-#include <siri/siri.h>
-#include <strextra/strextra.h>
-#include <sys/time.h>
-
-
-#define MAX_ITERATE_COUNT 10000 /* ten-thousand */
-#define MAX_BATCH_REQUIRE_SHARD 100 /* after reading 100 shards, iterate */
-
-#define QP_ADD_SUCCESS qp_add_raw( \
- query->packer, (const unsigned char *) "success_msg", 11);
-#define DEFAULT_ALLOC_COLUMNS 6
-#define IS_MASTER (query->flags & SIRIDB_QUERY_FLAG_MASTER)
-
-#define MASTER_CHECK_ONLINE(siridb) \
-if (IS_MASTER && !siridb_server_self_online(siridb->server)) \
-{ \
- sprintf(query->err_msg, \
- "Server '%s' is currently not available to process " \
- "this request", \
- siridb->server->name); \
- siridb_query_send_error(handle, CPROTO_ERR_SERVER); \
- return; \
-} \
-if (IS_MASTER && !siridb_pools_online(siridb)) \
-{ \
- sprintf(query->err_msg, \
- "At least one pool is lacking an online server to process " \
- "this request"); \
- siridb_query_send_error(handle, CPROTO_ERR_POOL); \
- return; \
-}
-
-#define MASTER_CHECK_VERSION(siridb, _VERSION) \
-if (IS_MASTER) \
-{ \
- int nservers = siridb_servers_check_version(siridb, _VERSION); \
- if (nservers) \
- { \
- sprintf(query->err_msg, \
- "At least %d server%s not running version %s " \
- "or greater which is required for this query.", \
- nservers, (nservers == 1) ? " is" : "s are", _VERSION); \
- siridb_query_send_error(handle, CPROTO_ERR_QUERY); \
- return; \
- } \
-}
-
-#define MASTER_CHECK_ACCESSIBLE(siridb) \
-if (IS_MASTER && !siridb_server_self_accessible(siridb->server)) \
-{ \
- sprintf(query->err_msg, \
- "Server '%s' is currently not accessible to process " \
- "this request", \
- siridb->server->name); \
- siridb_query_send_error(handle, CPROTO_ERR_SERVER); \
- return; \
-} \
-if (IS_MASTER && !siridb_pools_accessible(siridb)) \
-{ \
- sprintf(query->err_msg, \
- "At least one pool is lacking an accessible server to process " \
- "this request"); \
- siridb_query_send_error(handle, CPROTO_ERR_POOL); \
- return; \
-}
-
-#define MASTER_CHECK_REINDEXING(siridb) \
-if (IS_MASTER && siridb_is_reindexing(siridb)) \
-{ \
- sprintf(query->err_msg, \
- "SiriDB cannot perform this request because the database is " \
- "currently re-indexing"); \
- siridb_query_send_error(handle, CPROTO_ERR_POOL); \
- return; \
-}
-
-#define ON_PROMISES \
- siri_async_decref(&handle); \
- if (promises == NULL) \
- { \
- return; /* signal is raised when handle is NULL */ \
- } \
- if (handle == NULL) \
- { \
- sirinet_promises_llist_free(promises); \
- return; /* signal is raised when handle is NULL */ \
- }
-
-#define MEM_ERR_RET \
- sprintf(query->err_msg, "Memory allocation error."); \
- siridb_query_send_error(handle, CPROTO_ERR_QUERY); \
- return;
-
-#define FILE_ERR_RET \
- sprintf(query->err_msg, "File error occurred."); \
- siridb_query_send_error(handle, CPROTO_ERR_QUERY); \
- return;
-
-#define MSG_SUCCESS_CREATE_USER \
- "Successfully created user '%s'."
-#define MSG_SUCCESS_DROP_USER \
- "Successfully dropped user '%s'."
-#define MSG_SUCCESS_ALTER_USER \
- "Successfully updated user '%s'."
-#define MSG_SUCCESS_GRANT_USER \
- "Successfully granted permissions to user '%s'."
-#define MSG_SUCCESS_REVOKE_USER \
- "Successfully revoked permissions from user '%s'."
-#define MSG_SUCCESS_CREATE_GROUP \
- "Successfully created group '%s'."
-#define MSG_SUCCESS_DROP_GROUP \
- "Successfully dropped group '%s'."
-#define MSG_SUCCESS_ALTER_GROUP \
- "Successfully updated group '%s'."
-#define MSG_SUCCESS_SET_DROP_THRESHOLD \
- "Successfully changed drop_threshold from %g to %g."
-#define MSG_SUCCESS_SET_LIST_LIMIT \
- "Successfully changed list limit from %" PRIu32 " to %" PRIu32 "."
-#define MSG_SUCCESS_SET_ADDR_PORT \
- "Successfully changed server address to '%s'."
-#define MSG_SUCCESS_DROP_SERVER \
- "Successfully dropped server '%s'."
-#define MSG_SUCCES_SET_LOG_LEVEL_MULTI \
- "Successfully set log level to '%s' on %lu servers."
-#define MSG_SUCCES_SET_LOG_LEVEL \
- "Successfully set log level to '%s' on '%s'."
-#define MSG_SUCCESS_SET_SELECT_POINTS_LIMIT \
- "Successfully changed select points limit from %" PRIu32 " to %" PRIu32 "."
-#define MSG_SUCCES_DROP_SERIES \
- "Successfully dropped %lu series."
-#define MSG_SUCCES_DROP_SHARDS \
- "Successfully dropped %lu shards. (this number does not include " \
- "shards which are dropped on replica servers)"
-#define MSG_SUCCES_SET_BACKUP_MODE \
- "Successfully %s backup mode on '%s'."
-#define MSG_SUCCES_SET_TIMEZONE \
- "Successfully changed timezone from '%s' to '%s'."
-#define MSG_ERR_SERVER_ADDRESS \
- "Its only possible to change a servers address or port when the server " \
- "is not connected."
-
-
-static void enter_access_expr(uv_async_t * handle);
-static void enter_alter_group(uv_async_t * handle);
-static void enter_alter_server(uv_async_t * handle);
-static void enter_alter_servers(uv_async_t * handle);
-static void enter_alter_stmt(uv_async_t * handle);
-static void enter_alter_user(uv_async_t * handle);
-static void enter_count_stmt(uv_async_t * handle);
-static void enter_create_stmt(uv_async_t * handle);
-static void enter_create_user(uv_async_t * handle);
-static void enter_drop_stmt(uv_async_t * handle);
-static void enter_grant_user(uv_async_t * handle);
-static void enter_group_match(uv_async_t * handle);
-static void enter_help(uv_async_t * handle);
-static void enter_limit_expr(uv_async_t * handle);
-static void enter_list_stmt(uv_async_t * handle);
-static void enter_merge_as(uv_async_t * handle);
-static void enter_revoke_user(uv_async_t * handle);
-static void enter_select_stmt(uv_async_t * handle);
-static void enter_set_expression(uv_async_t * handle);
-static void enter_set_ignore_threshold(uv_async_t * handle);
-static void enter_set_name(uv_async_t * handle);
-static void enter_set_password(uv_async_t * handle);
-static void enter_series_all(uv_async_t * handle);
-static void enter_series_name(uv_async_t * handle);
-static void enter_series_match(uv_async_t * handle);
-static void enter_series_re(uv_async_t * handle);
-static void enter_series_sep(uv_async_t * handle);
-static void enter_timeit_stmt(uv_async_t * handle);
-static void enter_where_xxx(uv_async_t * handle);
-static void enter_xxx_columns(uv_async_t * handle);
-
-static void exit_after_expr(uv_async_t * handle);
-static void exit_alter_group(uv_async_t * handle);
-static void exit_alter_user(uv_async_t * handle);
-static void exit_before_expr(uv_async_t * handle);
-static void exit_between_expr(uv_async_t * handle);
-static void exit_calc_stmt(uv_async_t * handle);
-static void exit_count_groups(uv_async_t * handle);
-static void exit_count_pools(uv_async_t * handle);
-static void exit_count_series(uv_async_t * handle);
-static void exit_count_series_length(uv_async_t * handle);
-static void exit_count_servers(uv_async_t * handle);
-static void exit_count_servers_received(uv_async_t * handle);
-static void exit_count_servers_selected(uv_async_t * handle);
-static void exit_count_shards(uv_async_t * handle);
-static void exit_count_shards_size(uv_async_t * handle);
-static void exit_count_users(uv_async_t * handle);
-static void exit_create_group(uv_async_t * handle);
-static void exit_create_user(uv_async_t * handle);
-static void exit_drop_group(uv_async_t * handle);
-static void exit_drop_series(uv_async_t * handle);
-static void exit_drop_server(uv_async_t * handle);
-static void exit_drop_shards(uv_async_t * handle);
-static void exit_drop_user(uv_async_t * handle);
-static void exit_grant_user(uv_async_t * handle);
-static void exit_help_xxx(uv_async_t * handle);
-static void exit_list_groups(uv_async_t * handle);
-static void exit_list_pools(uv_async_t * handle);
-static void exit_list_series(uv_async_t * handle);
-static void exit_list_servers(uv_async_t * handle);
-static void exit_list_shards(uv_async_t * handle);
-static void exit_list_users(uv_async_t * handle);
-static void exit_revoke_user(uv_async_t * handle);
-static void exit_select_aggregate(uv_async_t * handle);
-static void exit_select_stmt(uv_async_t * handle);
-static void exit_series_match(uv_async_t * handle);
-static void exit_set_address(uv_async_t * handle);
-static void exit_set_backup_mode(uv_async_t * handle);
-static void exit_set_drop_threshold(uv_async_t * handle);
-static void exit_set_list_limit(uv_async_t * handle);
-static void exit_set_log_level(uv_async_t * handle);
-static void exit_set_port(uv_async_t * handle);
-static void exit_set_select_points_limit(uv_async_t * handle);
-static void exit_set_timezone(uv_async_t * handle);
-static void exit_show_stmt(uv_async_t * handle);
-static void exit_timeit_stmt(uv_async_t * handle);
-
-/* async loop functions */
-static void async_count_series(uv_async_t * handle);
-static void async_count_series_length(uv_async_t * handle);
-static void async_drop_series(uv_async_t * handle);
-static void async_drop_shards(uv_async_t * handle);
-static void async_filter_series(uv_async_t * handle);
-static void async_list_series(uv_async_t * handle);
-static void async_no_points_aggregate(uv_async_t * handle);
-static void async_select_aggregate(uv_async_t * handle);
-static void async_series_re(uv_async_t * handle);
-
-/* on response functions */
-static void on_ack_response(
- sirinet_promise_t * promise,
- sirinet_pkg_t * pkg,
- int status);
-static void on_alter_xxx_response(slist_t * promises, uv_async_t * handle);
-static void on_count_xxx_response(slist_t * promises, uv_async_t * handle);
-static void on_drop_series_response(slist_t * promises, uv_async_t * handle);
-static void on_drop_shards_response(slist_t * promises, uv_async_t * handle);
-static void on_groups_response(slist_t * promises, uv_async_t * handle);
-static void on_list_xxx_response(slist_t * promises, uv_async_t * handle);
-static void on_select_response(slist_t * promises, uv_async_t * handle);
-static void on_update_xxx_response(slist_t * promises, uv_async_t * handle);
-
-/* helper functions */
-static void master_select_work(uv_work_t * handle);
-static void master_select_work_finish(uv_work_t * work, int status);
-static int items_select_master(
- const char * name,
- size_t len,
- siridb_points_t * points,
- uv_async_t * handle);
-static int items_select_master_merge(
- const char * name,
- size_t len,
- slist_t * plist,
- uv_async_t * handle);
-static int items_select_other(
- const char * name,
- size_t len,
- siridb_points_t * points,
- uv_async_t * handle);
-static int items_select_other_merge(
- const char * name,
- size_t len,
- slist_t * plist,
- uv_async_t * handle);
-static void on_select_unpack_points(
- qp_unpacker_t * unpacker,
- query_select_t * q_select,
- qp_obj_t * qp_name,
- qp_obj_t * qp_tp,
- qp_obj_t * qp_len,
- qp_obj_t * qp_points,
- uint32_t select_points_limit);
-static void on_select_unpack_merged_points(
- qp_unpacker_t * unpacker,
- query_select_t * q_select,
- qp_obj_t * qp_name,
- qp_obj_t * qp_tp,
- qp_obj_t * qp_len,
- qp_obj_t * qp_points,
- uint32_t select_points_limit);
-
-static int values_list_groups(siridb_group_t * group, uv_async_t * handle);
-static int values_count_groups(siridb_group_t * group, uv_async_t * handle);
-static void finish_list_groups(uv_async_t * handle);
-static void finish_count_groups(uv_async_t * handle);
-
-/* address bindings for default list properties */
-static uint32_t GID_K_NAME = CLERI_GID_K_NAME;
-static uint32_t GID_K_POOL = CLERI_GID_K_POOL;
-static uint32_t GID_K_VERSION = CLERI_GID_K_VERSION;
-static uint32_t GID_K_ONLINE = CLERI_GID_K_ONLINE;
-static uint32_t GID_K_STATUS = CLERI_GID_K_STATUS;
-static uint32_t GID_K_SERVER = CLERI_GID_K_SERVER;
-static uint32_t GID_K_SERVERS = CLERI_GID_K_SERVERS;
-static uint32_t GID_K_SERIES = CLERI_GID_K_SERIES;
-static uint32_t GID_K_SID = CLERI_GID_K_SID;
-static uint32_t GID_K_START = CLERI_GID_K_START;
-static uint32_t GID_K_END = CLERI_GID_K_END;
-
-/*
- * Start SIRIPARSER_ASYNC_NEXT_NODE
- */
-#define SIRIPARSER_ASYNC_NEXT_NODE \
-siridb_nodes_next(&query->nodes); \
-if (query->nodes == NULL) \
-{ \
- siridb_send_query_result(handle); \
-} \
-else \
-{ \
- uv_close((uv_handle_t *) handle, (uv_close_cb) free); \
- handle = (uv_async_t *) malloc(sizeof(uv_async_t)); \
- if (handle == NULL) \
- { \
- ERR_ALLOC \
- } \
- else \
- { \
- handle->data = query; \
- uv_async_init(siri.loop, handle, (uv_async_cb) query->nodes->cb); \
- uv_async_send(handle); \
- } \
-}
-
-#define SIRIPARSER_NEXT_NODE \
-siridb_nodes_next(&query->nodes); \
-if (query->nodes == NULL) \
-{ \
- siridb_send_query_result(handle); \
-} \
-else \
-{ \
- handle->data = query; \
- query->nodes->cb(handle); \
-}
-
-
-/*
- * Start SIRIPARSER_MASTER_CHECK_ACCESS
- */
-#define SIRIPARSER_MASTER_CHECK_ACCESS(user, ACCESS_BIT) \
-if (IS_MASTER && \
- !siridb_user_check_access( \
- user, \
- ACCESS_BIT, \
- query->err_msg)) \
-{ \
- siridb_query_send_error(handle, CPROTO_ERR_USER_ACCESS); \
- return; \
-}
-
-void siriparser_init_listener(void)
-{
- uint_fast16_t i;
-
- for (i = 0; i < CLERI_END; i++)
- {
- siriparser_listen_enter[i] = NULL;
- siriparser_listen_exit[i] = NULL;
- }
-
- siriparser_listen_enter[CLERI_GID_ACCESS_EXPR] = enter_access_expr;
- siriparser_listen_enter[CLERI_GID_ALTER_GROUP] = enter_alter_group;
- siriparser_listen_enter[CLERI_GID_ALTER_SERVER] = enter_alter_server;
- siriparser_listen_enter[CLERI_GID_ALTER_SERVERS] = enter_alter_servers;
- siriparser_listen_enter[CLERI_GID_ALTER_STMT] = enter_alter_stmt;
- siriparser_listen_enter[CLERI_GID_ALTER_USER] = enter_alter_user;
- siriparser_listen_enter[CLERI_GID_COUNT_STMT] = enter_count_stmt;
- siriparser_listen_enter[CLERI_GID_CREATE_STMT] = enter_create_stmt;
- siriparser_listen_enter[CLERI_GID_CREATE_USER] = enter_create_user;
- siriparser_listen_enter[CLERI_GID_DROP_STMT] = enter_drop_stmt;
- siriparser_listen_enter[CLERI_GID_GRANT_USER] = enter_grant_user;
- siriparser_listen_enter[CLERI_GID_GROUP_COLUMNS] = enter_xxx_columns;
- siriparser_listen_enter[CLERI_GID_GROUP_MATCH] = enter_group_match;
- siriparser_listen_enter[CLERI_GID_HELP_STMT] = enter_help;
- siriparser_listen_enter[CLERI_GID_LIMIT_EXPR] = enter_limit_expr;
- siriparser_listen_enter[CLERI_GID_LIST_STMT] = enter_list_stmt;
- siriparser_listen_enter[CLERI_GID_MERGE_AS] = enter_merge_as;
- siriparser_listen_enter[CLERI_GID_POOL_COLUMNS] = enter_xxx_columns;
- siriparser_listen_enter[CLERI_GID_REVOKE_USER] = enter_revoke_user;
- siriparser_listen_enter[CLERI_GID_SELECT_STMT] = enter_select_stmt;
- siriparser_listen_enter[CLERI_GID_SET_EXPRESSION] = enter_set_expression;
- siriparser_listen_enter[CLERI_GID_SET_IGNORE_THRESHOLD] = enter_set_ignore_threshold;
- siriparser_listen_enter[CLERI_GID_SET_NAME] = enter_set_name;
- siriparser_listen_enter[CLERI_GID_SET_PASSWORD] = enter_set_password;
- siriparser_listen_enter[CLERI_GID_SERIES_COLUMNS] = enter_xxx_columns;
- siriparser_listen_enter[CLERI_GID_SERVER_COLUMNS] = enter_xxx_columns;
- siriparser_listen_enter[CLERI_GID_SERIES_ALL] = enter_series_all;
- siriparser_listen_enter[CLERI_GID_SERIES_NAME] = enter_series_name;
- siriparser_listen_enter[CLERI_GID_SERIES_MATCH] = enter_series_match;
- siriparser_listen_enter[CLERI_GID_SERIES_RE] = enter_series_re;
- siriparser_listen_enter[CLERI_GID_SERIES_SEP] = enter_series_sep;
- siriparser_listen_enter[CLERI_GID_SHARD_COLUMNS] = enter_xxx_columns;
- siriparser_listen_enter[CLERI_GID_TIMEIT_STMT] = enter_timeit_stmt;
- siriparser_listen_enter[CLERI_GID_USER_COLUMNS] = enter_xxx_columns;
- siriparser_listen_enter[CLERI_GID_WHERE_GROUP] = enter_where_xxx;
- siriparser_listen_enter[CLERI_GID_WHERE_POOL] = enter_where_xxx;
- siriparser_listen_enter[CLERI_GID_WHERE_SERIES] = enter_where_xxx;
- siriparser_listen_enter[CLERI_GID_WHERE_SERVER] = enter_where_xxx;
- siriparser_listen_enter[CLERI_GID_WHERE_SHARD] = enter_where_xxx;
- siriparser_listen_enter[CLERI_GID_WHERE_USER] = enter_where_xxx;
-
-
- siriparser_listen_exit[CLERI_GID_AFTER_EXPR] = exit_after_expr;
- siriparser_listen_exit[CLERI_GID_ALTER_GROUP] = exit_alter_group;
- siriparser_listen_exit[CLERI_GID_ALTER_USER] = exit_alter_user;
- siriparser_listen_exit[CLERI_GID_BEFORE_EXPR] = exit_before_expr;
- siriparser_listen_exit[CLERI_GID_BETWEEN_EXPR] = exit_between_expr;
- siriparser_listen_exit[CLERI_GID_CALC_STMT] = exit_calc_stmt;
- siriparser_listen_exit[CLERI_GID_COUNT_GROUPS] = exit_count_groups;
- siriparser_listen_exit[CLERI_GID_COUNT_POOLS] = exit_count_pools;
- siriparser_listen_exit[CLERI_GID_COUNT_SERIES] = exit_count_series;
- siriparser_listen_exit[CLERI_GID_COUNT_SERIES_LENGTH] = exit_count_series_length;
- siriparser_listen_exit[CLERI_GID_COUNT_SERVERS] = exit_count_servers;
- siriparser_listen_exit[CLERI_GID_COUNT_SERVERS_RECEIVED] = exit_count_servers_received;
- siriparser_listen_exit[CLERI_GID_COUNT_SERVERS_SELECTED] = exit_count_servers_selected;
- siriparser_listen_exit[CLERI_GID_COUNT_SHARDS] = exit_count_shards;
- siriparser_listen_exit[CLERI_GID_COUNT_SHARDS_SIZE] = exit_count_shards_size;
- siriparser_listen_exit[CLERI_GID_COUNT_USERS] = exit_count_users;
- siriparser_listen_exit[CLERI_GID_CREATE_GROUP] = exit_create_group;
- siriparser_listen_exit[CLERI_GID_CREATE_USER] = exit_create_user;
- siriparser_listen_exit[CLERI_GID_DROP_GROUP] = exit_drop_group;
- siriparser_listen_exit[CLERI_GID_DROP_SERIES] = exit_drop_series;
- siriparser_listen_exit[CLERI_GID_DROP_SERVER] = exit_drop_server;
- siriparser_listen_exit[CLERI_GID_DROP_SHARDS] = exit_drop_shards;
- siriparser_listen_exit[CLERI_GID_DROP_USER] = exit_drop_user;
- siriparser_listen_exit[CLERI_GID_GRANT_USER] = exit_grant_user;
- siriparser_listen_exit[CLERI_GID_LIST_GROUPS] = exit_list_groups;
- siriparser_listen_exit[CLERI_GID_LIST_POOLS] = exit_list_pools;
- siriparser_listen_exit[CLERI_GID_LIST_SERIES] = exit_list_series;
- siriparser_listen_exit[CLERI_GID_LIST_SERVERS] = exit_list_servers;
- siriparser_listen_exit[CLERI_GID_LIST_SHARDS] = exit_list_shards;
- siriparser_listen_exit[CLERI_GID_LIST_USERS] = exit_list_users;
- siriparser_listen_exit[CLERI_GID_REVOKE_USER] = exit_revoke_user;
- siriparser_listen_exit[CLERI_GID_SELECT_AGGREGATE] = exit_select_aggregate;
- siriparser_listen_exit[CLERI_GID_SELECT_STMT] = exit_select_stmt;
- siriparser_listen_exit[CLERI_GID_SERIES_MATCH] = exit_series_match;
- siriparser_listen_exit[CLERI_GID_SET_ADDRESS] = exit_set_address;
- siriparser_listen_exit[CLERI_GID_SET_BACKUP_MODE] = exit_set_backup_mode;
- siriparser_listen_exit[CLERI_GID_SET_DROP_THRESHOLD] = exit_set_drop_threshold;
- siriparser_listen_exit[CLERI_GID_SET_LIST_LIMIT] = exit_set_list_limit;
- siriparser_listen_exit[CLERI_GID_SET_LOG_LEVEL] = exit_set_log_level;
- siriparser_listen_exit[CLERI_GID_SET_PORT] = exit_set_port;
- siriparser_listen_exit[CLERI_GID_SET_SELECT_POINTS_LIMIT] = exit_set_select_points_limit;
- siriparser_listen_exit[CLERI_GID_SET_TIMEZONE] = exit_set_timezone;
- siriparser_listen_exit[CLERI_GID_SHOW_STMT] = exit_show_stmt;
- siriparser_listen_exit[CLERI_GID_TIMEIT_STMT] = exit_timeit_stmt;
-
- for (i = HELP_OFFSET; i < HELP_OFFSET + HELP_COUNT; i++)
- {
- siriparser_listen_exit[i] = exit_help_xxx;
- }
-}
-
-/******************************************************************************
- * Enter functions
- *****************************************************************************/
-
-static void enter_access_expr(uv_async_t * handle)
-{
- siridb_query_t * query = (siridb_query_t *) handle->data;
-
- /* bind ACCESS_EXPR children to query */
- query->data = query->nodes->node->children;
-
- SIRIPARSER_NEXT_NODE
-}
-
-static void enter_alter_group(uv_async_t * handle)
-{
- siridb_query_t * query = (siridb_query_t *) handle->data;
- CLIENT_SIRIDB(query->client, siridb)
- query_alter_t * q_alter = (query_alter_t *) query->data;
-
- MASTER_CHECK_ACCESSIBLE(siridb)
-
- cleri_node_t * group_node =
- query->nodes->node->children->next->node;
- siridb_group_t * group;
-
- char name[group_node->len - 1];
- strx_extract_string(name, group_node->str, group_node->len);
-
- if ((group = ct_get(siridb->groups->groups, name)) == NULL)
- {
- snprintf(query->err_msg,
- SIRIDB_MAX_SIZE_ERR_MSG,
- "Cannot find group: '%s'",
- name);
- siridb_query_send_error(handle, CPROTO_ERR_QUERY);
- }
- else
- {
- q_alter->alter_tp = QUERY_ALTER_GROUP;
- q_alter->via.group = group;
- siridb_group_incref(group);
-
- SIRIPARSER_NEXT_NODE
- }
-}
-
-static void enter_alter_server(uv_async_t * handle)
-{
- siridb_query_t * query = (siridb_query_t *) handle->data;
- CLIENT_SIRIDB(query->client, siridb)
- query_alter_t * q_alter = (query_alter_t *) query->data;
- siridb_server_t * server = siridb_server_from_node(
- siridb,
- query->nodes->node->children->next->node->children->node,
- query->err_msg);
-
- if (server == NULL)
- {
- siridb_query_send_error(handle, CPROTO_ERR_QUERY);
- }
- else
- {
- q_alter->alter_tp = QUERY_ALTER_SERVER;
- q_alter->via.server = server;
- siridb_server_incref(server);
-
- SIRIPARSER_NEXT_NODE
- }
-}
-
-static void enter_alter_servers(uv_async_t * handle)
-{
- siridb_query_t * query = (siridb_query_t *) handle->data;
- ((query_alter_t *) query->data)->alter_tp = QUERY_ALTER_SERVERS;
-
- SIRIPARSER_NEXT_NODE
-}
-
-static void enter_alter_stmt(uv_async_t * handle)
-{
- siridb_query_t * query = (siridb_query_t *) handle->data;
-
- CLIENT_USER(query->client, siridb_user)
- SIRIPARSER_MASTER_CHECK_ACCESS(siridb_user, SIRIDB_ACCESS_ALTER)
-
-#if DEBUG
- assert (query->packer == NULL);
-#endif
-
- query->packer = sirinet_packer_new(1024);
-
- if (query->packer == NULL)
- {
- MEM_ERR_RET
- }
-
- qp_add_type(query->packer, QP_MAP_OPEN);
-
- query->data = query_alter_new();
-
- if (query->data == NULL)
- {
- MEM_ERR_RET
- }
- query->free_cb = (uv_close_cb) query_alter_free;
-
- SIRIPARSER_NEXT_NODE
-}
-
-static void enter_alter_user(uv_async_t * handle)
-{
- siridb_query_t * query = (siridb_query_t *) handle->data;
- CLIENT_SIRIDB(query->client, siridb)
-
- MASTER_CHECK_ACCESSIBLE(siridb)
-
- cleri_node_t * user_node =
- query->nodes->node->children->next->node;
- query_alter_t * q_alter = (query_alter_t *) query->data;
- siridb_user_t * user;
-
- char name[user_node->len - 1];
- strx_extract_string(name, user_node->str, user_node->len);
-
- if ((user = siridb_users_get_user(siridb->users, name, NULL)) == NULL)
- {
- snprintf(query->err_msg,
- SIRIDB_MAX_SIZE_ERR_MSG,
- "Cannot find user: '%s'",
- name);
- siridb_query_send_error(handle, CPROTO_ERR_QUERY);
- }
- else
- {
- q_alter->alter_tp = QUERY_ALTER_USER;
- q_alter->via.user = user;
- siridb_user_incref(user);
-
- SIRIPARSER_NEXT_NODE
- }
-}
-
-static void enter_count_stmt(uv_async_t * handle)
-{
- siridb_query_t * query = (siridb_query_t *) handle->data;
-
- CLIENT_USER(query->client, siridb_user)
- SIRIPARSER_MASTER_CHECK_ACCESS(siridb_user, SIRIDB_ACCESS_COUNT)
-
-#if DEBUG
- assert (query->packer == NULL);
-#endif
-
- query->packer = sirinet_packer_new(256);
-
- if (query->packer == NULL)
- {
- MEM_ERR_RET
- }
-
- qp_add_type(query->packer, QP_MAP_OPEN);
-
- query->data = query_count_new();
-
- if (query->data == NULL)
- {
- MEM_ERR_RET
- }
-
- query->free_cb = (uv_close_cb) query_count_free;
-
- SIRIPARSER_NEXT_NODE
-}
-
-static void enter_create_stmt(uv_async_t * handle)
-{
- siridb_query_t * query = (siridb_query_t *) handle->data;
-
- CLIENT_USER(query->client, siridb_user)
- SIRIPARSER_MASTER_CHECK_ACCESS(siridb_user, SIRIDB_ACCESS_CREATE)
-
- SIRIPARSER_NEXT_NODE
-}
-
-static void enter_create_user(uv_async_t * handle)
-{
- siridb_query_t * query = (siridb_query_t *) handle->data;
-
- /* bind user object to data and set correct free call */
- query_alter_t * q_alter = query_alter_new();
-
- query->data = q_alter;
-
- if (q_alter == NULL)
- {
- MEM_ERR_RET
- }
-
- query->free_cb = (uv_close_cb) query_alter_free;
- q_alter->via.user = siridb_user_new();
-
- if (q_alter->via.user == NULL)
- {
- MEM_ERR_RET
- }
-
- q_alter->alter_tp = QUERY_ALTER_USER;
-
- SIRIPARSER_NEXT_NODE
-}
-
-static void enter_drop_stmt(uv_async_t * handle)
-{
- siridb_query_t * query = (siridb_query_t *) handle->data;
-
-#if DEBUG
- assert (query->packer == NULL);
-#endif
-
- CLIENT_USER(query->client, siridb_user)
- SIRIPARSER_MASTER_CHECK_ACCESS(siridb_user, SIRIDB_ACCESS_DROP)
-
- query->packer = sirinet_packer_new(1024);
-
- if (query->packer == NULL)
- {
- MEM_ERR_RET
- }
-
- qp_add_type(query->packer, QP_MAP_OPEN);
-
- query->data = query_drop_new();
-
- if (query->data == NULL)
- {
- MEM_ERR_RET
- }
-
- query->free_cb = (uv_close_cb) query_drop_free;
-
- SIRIPARSER_NEXT_NODE
-}
-
-static void enter_grant_user(uv_async_t * handle)
-{
- siridb_query_t * query = (siridb_query_t *) handle->data;
- CLIENT_SIRIDB(query->client, siridb)
- CLIENT_USER(query->client, siridb_user)
- SIRIPARSER_MASTER_CHECK_ACCESS(siridb_user, SIRIDB_ACCESS_GRANT)
- MASTER_CHECK_ACCESSIBLE(siridb)
-
- cleri_node_t * user_node =
- query->nodes->node->children->next->node;
- siridb_user_t * user;
- char username[user_node->len - 1];
- strx_extract_string(username, user_node->str, user_node->len);
-
- if ((user = siridb_users_get_user(siridb->users, username, NULL)) == NULL)
- {
- snprintf(query->err_msg, SIRIDB_MAX_SIZE_ERR_MSG,
- "Cannot find user: '%s'", username);
- siridb_query_send_error(handle, CPROTO_ERR_QUERY);
- }
- else
- {
- user->access_bit |=
- siridb_access_from_children((cleri_children_t *) query->data);
-
- query_alter_t * q_alter = query->data = query_alter_new();
- if (q_alter == NULL)
- {
- MEM_ERR_RET
- }
-
- siridb_user_incref(user);
-
- query->free_cb = (uv_close_cb) query_alter_free;
- q_alter->alter_tp = QUERY_ALTER_USER;
- q_alter->via.user = user;
-
- SIRIPARSER_NEXT_NODE
- }
-}
-static void enter_group_match(uv_async_t * handle)
-{
- siridb_query_t * query = (siridb_query_t *) handle->data;
- CLIENT_SIRIDB(query->client, siridb)
- cleri_node_t * node = query->nodes->node;
- query_wrapper_t * q_wrapper = (query_wrapper_t *) query->data;
-
- /* we must send this query to all pools */
- if (q_wrapper->pmap != NULL)
- {
- imap_free(q_wrapper->pmap, NULL);
- q_wrapper->pmap = NULL;
- }
-
- char group_name[node->len - 1];
-
- /* extract series name */
- strx_extract_string(group_name, node->str, node->len);
-
- siridb_group_t * group =
- (siridb_group_t *) ct_get(siridb->groups->groups, group_name);
-
- if (group == NULL)
- {
- snprintf(query->err_msg,
- SIRIDB_MAX_SIZE_ERR_MSG,
- "Cannot find group '%s'",
- group_name);
- siridb_query_send_error(handle, CPROTO_ERR_QUERY);
- }
- else
- {
- siridb_series_t * series;
- size_t i;
-
- q_wrapper->series_tmp = (q_wrapper->update_cb == NULL) ?
- q_wrapper->series_map : imap_new();
-
- if (q_wrapper->series_tmp == NULL)
- {
- MEM_ERR_RET
- }
-
- uv_mutex_lock(&siridb->groups->mutex);
-
- for (i = 0; i < group->series->len; i++)
- {
- series = (siridb_series_t *) group->series->data[i];
- siridb_series_incref(series);
- if (imap_add(q_wrapper->series_tmp, series->id, series))
- {
- log_critical("Cannot add series to temporary map.");
- siridb_series_decref(series);
- }
- }
-
- uv_mutex_unlock(&siridb->groups->mutex);
-
- if (q_wrapper->update_cb != NULL)
- {
- (*q_wrapper->update_cb)(
- q_wrapper->series_map,
- q_wrapper->series_tmp,
- (imap_free_cb) &siridb__series_decref);
- }
-
- q_wrapper->series_tmp = NULL;
-
- SIRIPARSER_ASYNC_NEXT_NODE
- }
-}
-
-static void enter_help(uv_async_t * handle)
-{
- siridb_query_t * query = (siridb_query_t *) handle->data;
-
- cleri_node_t * node = query->nodes->node;
-
- query->data = strndup(node->str, node->len);
-
- if (query->data == NULL)
- {
- MEM_ERR_RET
- }
-
- query->free_cb = (uv_close_cb) query_help_free;
-
- strx_split_join(query->data, ' ', '_');
-
- SIRIPARSER_ASYNC_NEXT_NODE
-}
-
-static void enter_limit_expr(uv_async_t * handle)
-{
- siridb_query_t * query = (siridb_query_t *) handle->data;
- CLIENT_SIRIDB(query->client, siridb)
- query_list_t * qlist = (query_list_t *) query->data;
- int64_t limit = query->nodes->node->children->next->node->result;
-
- if (limit <= 0 || limit > siridb->list_limit)
- {
- snprintf(query->err_msg, SIRIDB_MAX_SIZE_ERR_MSG,
- "Limit must be a value between 0 and %" PRIu32
- " but received: %" PRId64
- " (optionally the limit can be changed, "
- "see 'help alter database')",
- siridb->list_limit,
- limit);
- siridb_query_send_error(handle, CPROTO_ERR_QUERY);
- }
- else
- {
- qlist->limit = limit;
- SIRIPARSER_NEXT_NODE
- }
-}
-
-static void enter_list_stmt(uv_async_t * handle)
-{
- siridb_query_t * query = (siridb_query_t *) handle->data;
-
- CLIENT_USER(query->client, siridb_user)
- SIRIPARSER_MASTER_CHECK_ACCESS(siridb_user, SIRIDB_ACCESS_LIST)
-
-#if DEBUG
- assert (query->packer == NULL);
-#endif
-
- query->packer = sirinet_packer_new(QP_SUGGESTED_SIZE);
-
- if (query->packer == NULL)
- {
- MEM_ERR_RET
- }
-
- qp_add_type(query->packer, QP_MAP_OPEN);
-
- qp_add_raw(query->packer, (const unsigned char *) "columns", 7);
- qp_add_type(query->packer, QP_ARRAY_OPEN);
-
- query->data = query_list_new();
-
- if (query->data == NULL)
- {
- MEM_ERR_RET
- }
-
- query->free_cb = (uv_close_cb) query_list_free;
-
- SIRIPARSER_NEXT_NODE
-}
-
-static void enter_merge_as(uv_async_t * handle)
-{
- siridb_query_t * query = (siridb_query_t *) handle->data;
- query_select_t * q_select = (query_select_t *) query->data;
- cleri_node_t * node = query->nodes->node->children->next->next->node;
- q_select->merge_as = (char *) malloc(node->len - 1);
-
- if (q_select->merge_as == NULL)
- {
- MEM_ERR_RET
- }
-
- strx_extract_string(q_select->merge_as, node->str, node->len);
-
- if (IS_MASTER && query->nodes->node->children->next->next->next != NULL)
- {
- q_select->mlist = siridb_aggregate_list(
- query->nodes->node->children->next->next->next->node->
- children->node->children->next->node->children,
- query->err_msg);
-
- if (q_select->mlist == NULL)
- {
- siridb_query_send_error(handle, CPROTO_ERR_QUERY);
- return;
- }
- }
-
- SIRIPARSER_ASYNC_NEXT_NODE
-}
-
-static void enter_revoke_user(uv_async_t * handle)
-{
- siridb_query_t * query = (siridb_query_t *) handle->data;
- CLIENT_SIRIDB(query->client, siridb)
- CLIENT_USER(query->client, siridb_user)
- SIRIPARSER_MASTER_CHECK_ACCESS(siridb_user, SIRIDB_ACCESS_REVOKE)
- MASTER_CHECK_ACCESSIBLE(siridb)
-
- cleri_node_t * user_node =
- query->nodes->node->children->next->node;
- siridb_user_t * user;
- char username[user_node->len - 1];
- strx_extract_string(username, user_node->str, user_node->len);
-
- if ((user = siridb_users_get_user(siridb->users, username, NULL)) == NULL)
- {
- snprintf(query->err_msg,
- SIRIDB_MAX_SIZE_ERR_MSG,
- "Cannot find user: '%s'",
- username);
- siridb_query_send_error(handle, CPROTO_ERR_QUERY);
- }
- else
- {
- user->access_bit &=
- ~siridb_access_from_children((cleri_children_t *) query->data);
-
- query_alter_t * q_alter = query->data = query_alter_new();
-
- if (q_alter == NULL)
- {
- MEM_ERR_RET
- }
-
- siridb_user_incref(user);
-
- query->free_cb = (uv_close_cb) query_alter_free;
- q_alter->alter_tp = QUERY_ALTER_USER;
- q_alter->via.user = user;
-
- SIRIPARSER_NEXT_NODE
- }
-}
-
-static void enter_select_stmt(uv_async_t * handle)
-{
- siridb_query_t * query = (siridb_query_t *) handle->data;
- CLIENT_SIRIDB(query->client, siridb)
- query_select_t * q_select;
- cleri_children_t * child;
- int skip_get_points;
-
- CLIENT_USER(query->client, siridb_user)
- SIRIPARSER_MASTER_CHECK_ACCESS(siridb_user, SIRIDB_ACCESS_SELECT)
- MASTER_CHECK_ACCESSIBLE(siridb)
-
-#if DEBUG
- assert (query->packer == NULL && query->data == NULL);
-#endif
-
- query->data = q_select = query_select_new();
-
- if (q_select == NULL)
- {
- MEM_ERR_RET
- }
-
- /* this is not critical since pmap is allowed to be NULL */
- ((query_select_t *) query->data)->pmap =
- (!IS_MASTER || siridb_is_reindexing(siridb)) ?
- NULL : imap_new();
-
- /* child is always the ',' and child->next the node */
- child = query->nodes->node->children->next->node->children;
- skip_get_points = siridb_aggregate_can_skip(child);
-
- child = child->next;
- while (child != NULL)
- {
- if (skip_get_points && !siridb_aggregate_can_skip(child->next))
- {
- skip_get_points = 0;
- }
- q_select->nselects++;
- child = child->next->next;
- }
-
- if (skip_get_points)
- {
- q_select->flags |= QUERIES_SKIP_GET_POINTS;
- }
-
- query->free_cb = (uv_close_cb) query_select_free;
- query->packer = sirinet_packer_new(QP_SUGGESTED_SIZE);
-
- if (query->packer == NULL)
- {
- MEM_ERR_RET
- }
-
- qp_add_type(query->packer, QP_MAP_OPEN);
-
- SIRIPARSER_ASYNC_NEXT_NODE
-}
-
-static void enter_set_expression(uv_async_t * handle)
-{
- siridb_query_t * query = (siridb_query_t *) handle->data;
- CLIENT_SIRIDB(query->client, siridb)
- cleri_node_t * node = query->nodes->node->children->next->next->node;
- query_alter_t * q_alter = (query_alter_t *) query->data;
-
- if (siridb_group_update_expression(
- siridb->groups,
- q_alter->via.group,
- node->str,
- node->len,
- query->err_msg))
- {
- siridb_query_send_error(handle, CPROTO_ERR_QUERY);
- }
- else
- {
- SIRIPARSER_ASYNC_NEXT_NODE
- }
-}
-
-static void enter_set_ignore_threshold(uv_async_t * handle)
-{
- siridb_query_t * query = (siridb_query_t *) handle->data;
- query_drop_t * q_drop = (query_drop_t *) query->data;
-
- if ( query->nodes->node->children->next->next->node->children->node->
- cl_obj->gid == CLERI_GID_K_TRUE)
- {
- q_drop->flags |= QUERIES_IGNORE_DROP_THRESHOLD;
- }
-
- SIRIPARSER_NEXT_NODE
-}
-
-static void enter_set_name(uv_async_t * handle)
-{
- siridb_query_t * query = (siridb_query_t *) handle->data;
- CLIENT_SIRIDB(query->client, siridb)
- cleri_node_t * name_node =
- query->nodes->node->children->next->next->node;
-
- char name[name_node->len - 1];
- strx_extract_string(name, name_node->str, name_node->len);
-
- query_alter_t * q_alter = (query_alter_t *) query->data;
- switch (q_alter->alter_tp)
- {
- case QUERY_ALTER_USER:
- if (siridb_user_set_name(
- siridb,
- q_alter->via.user,
- name,
- query->err_msg))
- {
- siridb_query_send_error(handle, CPROTO_ERR_QUERY);
- return;
- }
- break;
- case QUERY_ALTER_GROUP:
- if (siridb_group_set_name(
- siridb->groups,
- q_alter->via.group,
- name,
- query->err_msg))
- {
- siridb_query_send_error(handle, CPROTO_ERR_QUERY);
- return;
- }
- break;
- case QUERY_ALTER_NONE:
- case QUERY_ALTER_DATABASE:
- case QUERY_ALTER_SERVER:
- default:
- assert (0);
- }
-
- SIRIPARSER_NEXT_NODE
-}
-
-static void enter_set_password(uv_async_t * handle)
-{
- siridb_query_t * query = (siridb_query_t *) handle->data;
- siridb_user_t * user = ((query_alter_t *) query->data)->via.user;
-
- cleri_node_t * pw_node =
- query->nodes->node->children->next->next->node;
-
- char password[pw_node->len - 1];
- strx_extract_string(password, pw_node->str, pw_node->len);
-
- if (siridb_user_set_password(user, password, query->err_msg))
- {
- siridb_query_send_error(handle, CPROTO_ERR_QUERY);
- }
- else
- {
- SIRIPARSER_NEXT_NODE
- }
-}
-
-static void enter_series_name(uv_async_t * handle)
-{
- siridb_query_t * query = (siridb_query_t *) handle->data;
- cleri_node_t * node = query->nodes->node;
- CLIENT_SIRIDB(query->client, siridb)
- query_wrapper_t * q_wrapper = (query_wrapper_t *) query->data;
- siridb_series_t * series = NULL;
- uint16_t pool;
- char series_name[node->len - 1];
-
- /* extract series name */
- strx_extract_string(series_name, node->str, node->len);
-
- if (siridb_is_reindexing(siridb))
- {
- series = (siridb_series_t *) ct_get(siridb->series, series_name);
- }
- else
- {
- /* get pool for series name */
- pool = siridb_lookup_sn(siridb->pools->lookup, series_name);
-
- /* check if this series belongs to 'this' pool and if so get the series */
- if (pool == siridb->server->pool)
- {
- series = (siridb_series_t *) ct_get(siridb->series, series_name);
- if (series == NULL)
- {
- /* the series does not exist */
- snprintf(query->err_msg, SIRIDB_MAX_SIZE_ERR_MSG,
- "Cannot find series: '%s'", series_name);
-
- /* free series_name and return with send_errror.. */
- siridb_query_send_error(handle, CPROTO_ERR_QUERY);
- return;
- }
- }
- else if (q_wrapper->pmap != NULL && imap_set(
- q_wrapper->pmap,
- pool,
- (siridb_pool_t *) (siridb->pools->pool + pool)) < 0)
- {
- log_critical("Cannot add pool to pool map.");
- }
- }
-
- if (series == NULL)
- {
- if (q_wrapper->update_cb == &imap_intersection_ref)
- {
- imap_free(
- q_wrapper->series_map,
- (imap_free_cb) &siridb__series_decref);
-
- q_wrapper->series_map = imap_new();
-
- if (q_wrapper->series_map == NULL)
- {
- MEM_ERR_RET
- }
- }
- }
- else
- {
- if ( q_wrapper->update_cb == NULL ||
- q_wrapper->update_cb == &imap_union_ref)
- {
- if (imap_set(q_wrapper->series_map, series->id, series) == 1)
- {
- siridb_series_incref(series);
- }
- }
- else if (q_wrapper->update_cb == &imap_difference_ref)
- {
- series = (siridb_series_t *) imap_pop(
- q_wrapper->series_map,
- series->id);
- if (series != NULL)
- {
- siridb_series_decref(series);
- }
- }
- else if (q_wrapper->update_cb == &imap_intersection_ref)
- {
- series = (siridb_series_t *) imap_get(
- q_wrapper->series_map,
- series->id);
-
- if (series != NULL)
- {
- siridb_series_incref(series);
- }
-
- imap_free(
- q_wrapper->series_map,
- (imap_free_cb) &siridb__series_decref);
-
- q_wrapper->series_map = imap_new();
-
- if (q_wrapper->series_map == NULL)
- {
- if (series != NULL)
- {
- siridb_series_decref(series);
- }
- MEM_ERR_RET
- }
-
- if (series != NULL)
- {
- if (imap_set(q_wrapper->series_map, series->id, series) != 1)
- {
- siridb_series_decref(series);
- MEM_ERR_RET
- }
- }
- }
- else if (q_wrapper->update_cb == &imap_symmetric_difference_ref)
- {
- switch (imap_set(q_wrapper->series_map, series->id, series))
- {
- case 0:
- series = (siridb_series_t *) imap_pop(
- q_wrapper->series_map,
- series->id);
- siridb_series_decref(series);
- break;
-
- case 1:
- siridb_series_incref(series);
- break;
-
- default:
- MEM_ERR_RET
- }
- }
- else
- {
- /* we should not get here */
- assert (0);
- }
- }
-
- SIRIPARSER_ASYNC_NEXT_NODE
-}
-
-static void enter_series_match(uv_async_t * handle)
-{
- siridb_query_t * query = (siridb_query_t *) handle->data;
-
- if ((((query_wrapper_t *) query->data)->series_map = imap_new()) == NULL)
- {
- MEM_ERR_RET
- }
-
- SIRIPARSER_NEXT_NODE
-}
-
-static void enter_series_all(uv_async_t * handle)
-{
- siridb_query_t * query = (siridb_query_t *) handle->data;
- CLIENT_SIRIDB(query->client, siridb)
- siridb_series_t * series;
- query_wrapper_t * q_wrapper = (query_wrapper_t *) query->data;
-
- /* we must send this query to all pools */
- if (q_wrapper->pmap != NULL)
- {
- imap_free(q_wrapper->pmap, NULL);
- q_wrapper->pmap = NULL;
- }
-
- uv_mutex_lock(&siridb->series_mutex);
-
- q_wrapper->slist = imap_2slist_ref(
- ( q_wrapper->update_cb == NULL ||
- q_wrapper->update_cb == &imap_union_ref ||
- q_wrapper->update_cb == &imap_symmetric_difference_ref) ?
- siridb->series_map : q_wrapper->series_map);
-
- uv_mutex_unlock(&siridb->series_mutex);
-
- q_wrapper->series_tmp = (q_wrapper->update_cb == NULL) ?
- q_wrapper->series_map : imap_new();
-
- if (q_wrapper->slist == NULL || q_wrapper->series_tmp == NULL)
- {
- MEM_ERR_RET
- }
-
- for (q_wrapper->slist_index = 0;
- q_wrapper->slist_index < q_wrapper->slist->len;
- ++q_wrapper->slist_index)
- {
- series = q_wrapper->slist->data[q_wrapper->slist_index];
- if (imap_add(q_wrapper->series_tmp, series->id, series))
- {
- MEM_ERR_RET
- }
- }
-
- slist_free(q_wrapper->slist);
- q_wrapper->slist = NULL;
- q_wrapper->slist_index = 0;
-
- if (q_wrapper->update_cb != NULL)
- {
- (*q_wrapper->update_cb)(
- q_wrapper->series_map,
- q_wrapper->series_tmp,
- (imap_free_cb) &siridb__series_decref);
- }
-
- q_wrapper->series_tmp = NULL;
- SIRIPARSER_ASYNC_NEXT_NODE
-}
-
-static void enter_series_re(uv_async_t * handle)
-{
- siridb_query_t * query = (siridb_query_t *) handle->data;
- CLIENT_SIRIDB(query->client, siridb)
- cleri_node_t * node = query->nodes->node;
- query_wrapper_t * q_wrapper = (query_wrapper_t *) query->data;
-
- /* we must send this query to all pools */
- if (q_wrapper->pmap != NULL)
- {
- imap_free(q_wrapper->pmap, NULL);
- q_wrapper->pmap = NULL;
- }
-
- /* extract and compile regular expression */
- if (siridb_re_compile(
- &q_wrapper->regex,
- &q_wrapper->match_data,
- node->str,
- node->len,
- query->err_msg))
- {
- siridb_query_send_error(handle, CPROTO_ERR_QUERY);
- }
- else
- {
- uv_mutex_lock(&siridb->series_mutex);
-
- q_wrapper->slist = imap_2slist_ref(
- ( q_wrapper->update_cb == NULL ||
- q_wrapper->update_cb == &imap_union_ref ||
- q_wrapper->update_cb == &imap_symmetric_difference_ref) ?
- siridb->series_map : q_wrapper->series_map);
-
- uv_mutex_unlock(&siridb->series_mutex);
-
- q_wrapper->series_tmp = (q_wrapper->update_cb == NULL) ?
- q_wrapper->series_map : imap_new();
-
- if (q_wrapper->slist == NULL || q_wrapper->series_tmp == NULL)
- {
- MEM_ERR_RET
- }
-
- uv_async_t * next =
- (uv_async_t *) malloc(sizeof(uv_async_t));
-
- if (next == NULL)
- {
- MEM_ERR_RET
- }
-
- next->data = handle->data;
-
- uv_async_init(
- siri.loop,
- next,
- (uv_async_cb) async_series_re);
- uv_async_send(next);
-
- uv_close((uv_handle_t *) handle, (uv_close_cb) free);
- }
-
- /* handle is handled or a signal is raised */
-}
-
-static void enter_series_sep(uv_async_t * handle)
-{
- siridb_query_t * query = (siridb_query_t *) handle->data;
- query_wrapper_t * q_wrapper = (query_wrapper_t *) query->data;
-
- switch (query->nodes->node->children->node->cl_obj->gid)
- {
- case CLERI_GID_K_UNION:
- q_wrapper->update_cb = &imap_union_ref;
- break;
- case CLERI_GID_K_INTERSECTION:
- q_wrapper->update_cb = &imap_intersection_ref;
- break;
- case CLERI_GID_C_DIFFERENCE:
- q_wrapper->update_cb = &imap_difference_ref;
- break;
- case CLERI_GID_K_SYMMETRIC_DIFFERENCE:
- q_wrapper->update_cb = &imap_symmetric_difference_ref;
- break;
- default:
- assert (0);
- break;
- }
-
- SIRIPARSER_NEXT_NODE
-}
-
-static void enter_timeit_stmt(uv_async_t * handle)
-{
- siridb_query_t * query = (siridb_query_t *) handle->data;
- query->timeit = qp_packer_new(512);
-
- if (query->timeit == NULL)
- {
- MEM_ERR_RET
- }
-
- qp_add_raw(query->timeit, (const unsigned char *) "__timeit__", 10);
- qp_add_type(query->timeit, QP_ARRAY_OPEN);
-
- SIRIPARSER_NEXT_NODE
-}
-
-static void enter_where_xxx(uv_async_t * handle)
-{
- siridb_query_t * query = (siridb_query_t *) handle->data;
- cexpr_t * cexpr =
- cexpr_from_node(query->nodes->node->children->next->node);
-
- if (cexpr == NULL)
- {
- sprintf(query->err_msg, "Max depth reached in 'where' expression!");
- siridb_query_send_error(handle, CPROTO_ERR_QUERY);
- }
- else
- {
- ((query_wrapper_t *) query->data)->where_expr = cexpr;
- SIRIPARSER_ASYNC_NEXT_NODE
- }
-}
-
-static void enter_xxx_columns(uv_async_t * handle)
-{
- siridb_query_t * query = (siridb_query_t *) handle->data;
- cleri_children_t * columns = query->nodes->node->children;
- query_list_t * qlist = (query_list_t *) query->data;
-
- qlist->props = slist_new(DEFAULT_ALLOC_COLUMNS);
-
- if (qlist->props == NULL)
- {
- MEM_ERR_RET
- }
-
- while (1)
- {
- qp_add_raw(
- query->packer,
- (const unsigned char *) columns->node->str,
- columns->node->len);
-
- if (slist_append_safe(
- &qlist->props,
- &columns->node->children->node->cl_obj->gid))
- {
- MEM_ERR_RET
- }
-
- if (columns->next == NULL)
- {
- break;
- }
-
- columns = columns->next->next;
- }
-
- SIRIPARSER_ASYNC_NEXT_NODE
-}
-
-/******************************************************************************
- * Exit functions
- *****************************************************************************/
-
-static void exit_after_expr(uv_async_t * handle)
-{
- siridb_query_t * query = (siridb_query_t *) handle->data;
- ((query_select_t *) query->data)->start_ts =
- (uint64_t *) &query->nodes->node->children->next->node->result;
-
- SIRIPARSER_NEXT_NODE
-}
-
-static void exit_alter_group(uv_async_t * handle)
-{
- siridb_query_t * query = (siridb_query_t *) handle->data;
- CLIENT_SIRIDB(query->client, siridb)
-
- if (siridb_groups_save(siridb->groups))
- {
- FILE_ERR_RET
- }
-
- QP_ADD_SUCCESS
- char * name = ((query_alter_t *) query->data)->via.group->name;
- log_info(MSG_SUCCESS_ALTER_GROUP, name);
- qp_add_fmt_safe(query->packer, MSG_SUCCESS_ALTER_GROUP, name);
-
- if (IS_MASTER)
- {
- siridb_query_forward(
- handle,
- SIRIDB_QUERY_FWD_UPDATE,
- (sirinet_promises_cb) on_update_xxx_response,
- 0);
- }
- else
- {
- SIRIPARSER_ASYNC_NEXT_NODE
- }
-}
-
-static void exit_alter_user(uv_async_t * handle)
-{
- siridb_query_t * query = (siridb_query_t *) handle->data;
- CLIENT_SIRIDB(query->client, siridb)
-
- if (siridb_users_save(siridb))
- {
- FILE_ERR_RET
- }
-
- QP_ADD_SUCCESS
- char * name = ((query_alter_t *) query->data)->via.user->name;
- log_info(MSG_SUCCESS_ALTER_USER, name);
- qp_add_fmt_safe(query->packer, MSG_SUCCESS_ALTER_USER, name);
-
- if (IS_MASTER)
- {
- siridb_query_forward(
- handle,
- SIRIDB_QUERY_FWD_UPDATE,
- (sirinet_promises_cb) on_update_xxx_response,
- 0);
- }
- else
- {
- SIRIPARSER_ASYNC_NEXT_NODE
- }
-}
-
-static void exit_before_expr(uv_async_t * handle)
-{
- siridb_query_t * query = (siridb_query_t *) handle->data;
-
- ((query_select_t *) query->data)->end_ts =
- (uint64_t *) &query->nodes->node->children->next->node->result;
-
- SIRIPARSER_NEXT_NODE
-}
-
-static void exit_between_expr(uv_async_t * handle)
-{
- siridb_query_t * query = (siridb_query_t *) handle->data;
- query_select_t * q_select = (query_select_t *) query->data;
-
- q_select->start_ts = (uint64_t *)
- &query->nodes->node->children->next->node->result;
-
- q_select->end_ts = (uint64_t *)
- &query->nodes->node->children->next->next->next->node->result;
-
- if (*q_select->start_ts > *q_select->end_ts)
- {
- snprintf(query->err_msg,
- SIRIDB_MAX_SIZE_ERR_MSG,
- "Start time (%" PRIu64 ") "
- "should not be greater than end time (%" PRIu64 ")",
- *q_select->start_ts,
- *q_select->end_ts);
- siridb_query_send_error(handle, CPROTO_ERR_QUERY);
- }
- else
- {
- SIRIPARSER_NEXT_NODE
- }
-}
-
-static void exit_calc_stmt(uv_async_t * handle)
-{
- siridb_query_t * query = (siridb_query_t *) handle->data;
- cleri_node_t * calc_node = query->nodes->node;
-
-#if DEBUG
- assert (query->packer == NULL);
-#endif
-
- query->packer = sirinet_packer_new(64);
-
- if (query->packer == NULL)
- {
- MEM_ERR_RET
- }
-
- qp_add_type(query->packer, QP_MAP_OPEN);
- qp_add_raw(query->packer, (const unsigned char *) "calc", 4);
-
- if (!query->factor)
- {
- qp_add_int64(query->packer, calc_node->result);
- }
- else
- {
- double factor = (double) query->factor;
- qp_add_int64(query->packer, (int64_t) (calc_node->result * factor));
- }
-
- SIRIPARSER_ASYNC_NEXT_NODE
-}
-
-static void exit_count_groups(uv_async_t * handle)
-{
- siridb_query_t * query = (siridb_query_t *) handle->data;
- CLIENT_SIRIDB(query->client, siridb)
- query_count_t * q_count = (query_count_t *) query->data;
-
- if (q_count->where_expr == NULL || !cexpr_contains(
- q_count->where_expr,
- siridb_group_is_remote_prop))
- {
- finish_count_groups(handle);
- }
- else
- {
- sirinet_pkg_t * pkg = sirinet_pkg_new(0, 0, BPROTO_REQ_GROUPS, NULL);
-
- if (pkg != NULL)
- {
- siri_async_incref(handle);
-
- query->nodes->cb = (uv_async_cb) finish_count_groups;
-
- siridb_pools_send_pkg(
- siridb,
- pkg,
- 0,
- (sirinet_promises_cb) on_groups_response,
- handle,
- 0);
- }
- }
-}
-
-static void exit_count_pools(uv_async_t * handle)
-{
- siridb_query_t * query = (siridb_query_t *) handle->data;
- CLIENT_SIRIDB(query->client, siridb)
- query_count_t * q_count = (query_count_t *) query->data;
- siridb_pool_t * pool = siridb->pools->pool + siridb->server->pool;
-
- siridb_pool_walker_t wpool = {
- .servers=pool->len,
- .series=siridb->series->len,
- .pool=siridb->server->pool
- };
-
- qp_add_raw(query->packer, (const unsigned char *) "pools", 5);
-
- if (q_count->where_expr == NULL)
- {
- qp_add_int64(query->packer, siridb->pools->len);
- SIRIPARSER_ASYNC_NEXT_NODE
- }
- else
- {
- MASTER_CHECK_ACCESSIBLE(siridb)
-
- q_count->n = cexpr_run(
- q_count->where_expr,
- (cexpr_cb_t) siridb_pool_cexpr_cb,
- &wpool);
-
- if (IS_MASTER)
- {
- siridb_query_forward(
- handle,
- SIRIDB_QUERY_FWD_POOLS,
- (sirinet_promises_cb) on_count_xxx_response,
- 0);
- }
- else
- {
- qp_add_int64(query->packer, q_count->n);
- SIRIPARSER_ASYNC_NEXT_NODE
- }
- }
-}
-
-static void exit_count_series(uv_async_t * handle)
-{
- siridb_query_t * query = (siridb_query_t *) handle->data;
- CLIENT_SIRIDB(query->client, siridb)
- query_count_t * q_count = (query_count_t *) query->data;
-
- MASTER_CHECK_ONLINE(siridb)
-
- qp_add_raw(query->packer, (const unsigned char *) "series", 6);
-
- if (q_count->where_expr == NULL)
- {
- q_count->n = (q_count->series_map == NULL) ?
- siridb->series_map->len : q_count->series_map->len;
-
- if (IS_MASTER)
- {
- siridb_query_forward(
- handle,
- SIRIDB_QUERY_FWD_POOLS,
- (sirinet_promises_cb) on_count_xxx_response,
- 0);
- }
- else
- {
- qp_add_int64(query->packer, q_count->n);
-
- SIRIPARSER_ASYNC_NEXT_NODE
- }
- }
- else
- {
- uv_mutex_lock(&siridb->series_mutex);
-
- q_count->slist = imap_2slist_ref(
- (q_count->series_map == NULL) ?
- siridb->series_map : q_count->series_map);
-
- uv_mutex_unlock(&siridb->series_mutex);
-
- if (q_count->slist == NULL)
- {
- MEM_ERR_RET
- }
-
- uv_async_t * next =
- (uv_async_t *) malloc(sizeof(uv_async_t));
- if (next == NULL)
- {
- MEM_ERR_RET
- }
-
- next->data = handle->data;
-
- uv_async_init(
- siri.loop,
- next,
- (uv_async_cb) async_count_series);
- uv_async_send(next);
-
- uv_close((uv_handle_t *) handle, (uv_close_cb) free);
- }
-}
-
-static void exit_count_series_length(uv_async_t * handle)
-{
- siridb_query_t * query = (siridb_query_t *) handle->data;
- CLIENT_SIRIDB(query->client, siridb)
- query_count_t * q_count = (query_count_t *) query->data;
-
- MASTER_CHECK_ACCESSIBLE(siridb)
-
- qp_add_raw(query->packer, (const unsigned char *) "series_length", 13);
-
- if (q_count->where_expr == NULL)
- {
- size_t i;
- slist_t * slist;
- siridb_series_t * series;
-
- uv_mutex_lock(&siridb->series_mutex);
-
- slist = imap_2slist((q_count->series_map == NULL) ?
- siridb->series_map : q_count->series_map);
-
- uv_mutex_unlock(&siridb->series_mutex);
-
- if (slist == NULL)
- {
- MEM_ERR_RET
- }
-
- for (i = 0; i < slist->len; i++)
- {
- series = (siridb_series_t *) slist->data[i];
- q_count->n += series->length;
- }
-
- slist_free(slist);
-
- if (IS_MASTER)
- {
- siridb_query_forward(
- handle,
- SIRIDB_QUERY_FWD_POOLS,
- (sirinet_promises_cb) on_count_xxx_response,
- 0);
- }
- else
- {
- qp_add_int64(query->packer, q_count->n);
-
- SIRIPARSER_ASYNC_NEXT_NODE
- }
- }
- else
- {
- uv_async_t * next;
-
- uv_mutex_lock(&siridb->series_mutex);
-
- q_count->slist = imap_2slist_ref(
- (q_count->series_map == NULL) ?
- siridb->series_map : q_count->series_map);
-
- uv_mutex_unlock(&siridb->series_mutex);
-
- if (q_count->slist == NULL)
- {
- MEM_ERR_RET
- }
-
- next = (uv_async_t *) malloc(sizeof(uv_async_t));
-
- if (next == NULL)
- {
- MEM_ERR_RET
- }
-
- next->data = handle->data;
-
- uv_async_init(
- siri.loop,
- next,
- (uv_async_cb) async_count_series_length);
- uv_async_send(next);
-
- uv_close((uv_handle_t *) handle, (uv_close_cb) free);
- }
-}
-
-static void exit_count_servers(uv_async_t * handle)
-{
- siridb_query_t * query = (siridb_query_t *) handle->data;
- CLIENT_SIRIDB(query->client, siridb)
- query_count_t * q_count = (query_count_t *) query->data;
- cexpr_t * where_expr = q_count->where_expr;
- cexpr_cb_t cb = (cexpr_cb_t) siridb_server_cexpr_cb;
- int is_local = IS_MASTER;
-
- qp_add_raw(query->packer, (const unsigned char *) "servers", 7);
-
-
- /* if is_local, check if we use 'remote' props in where expression */
- if (is_local && where_expr != NULL)
- {
- is_local = !cexpr_contains(where_expr, siridb_server_is_remote_prop);
- }
-
- if (is_local)
- {
- llist_node_t * node;
- for ( node = siridb->servers->first;
- node != NULL;
- node = node->next)
- {
- siridb_server_walker_t wserver = {node->data, siridb};
- if (where_expr == NULL || cexpr_run(where_expr, cb, &wserver))
- {
- q_count->n++;
- }
- }
- }
- else
- {
- siridb_server_walker_t wserver = {siridb->server, siridb};
- if (where_expr == NULL || cexpr_run(where_expr, cb, &wserver))
- {
- q_count->n++;
- }
- }
-
- if (IS_MASTER && !is_local)
- {
- siridb_query_forward(
- handle,
- SIRIDB_QUERY_FWD_SERVERS,
- (sirinet_promises_cb) on_count_xxx_response,
- 0);
- }
- else
- {
- qp_add_int64(query->packer, q_count->n);
- SIRIPARSER_ASYNC_NEXT_NODE
- }
-}
-
-static void exit_count_servers_received(uv_async_t * handle)
-{
- siridb_query_t * query = (siridb_query_t *) handle->data;
- CLIENT_SIRIDB(query->client, siridb)
- query_count_t * q_count = (query_count_t *) query->data;
- cexpr_t * where_expr = q_count->where_expr;
- cexpr_cb_t cb = (cexpr_cb_t) siridb_server_cexpr_cb;
-
- qp_add_raw(
- query->packer,
- (const unsigned char *) "servers_received_points",
- 23);
-
- siridb_server_walker_t wserver = {siridb->server, siridb};
- if (where_expr == NULL || cexpr_run(where_expr, cb, &wserver))
- {
- q_count->n += siridb->received_points;
- }
-
- if (IS_MASTER)
- {
- siridb_query_forward(
- handle,
- SIRIDB_QUERY_FWD_SERVERS,
- (sirinet_promises_cb) on_count_xxx_response,
- 0);
- }
- else
- {
- qp_add_int64(query->packer, q_count->n);
- SIRIPARSER_ASYNC_NEXT_NODE
- }
-}
-
-static void exit_count_servers_selected(uv_async_t * handle)
-{
- siridb_query_t * query = (siridb_query_t *) handle->data;
- CLIENT_SIRIDB(query->client, siridb)
- query_count_t * q_count = (query_count_t *) query->data;
- cexpr_t * where_expr = q_count->where_expr;
- cexpr_cb_t cb = (cexpr_cb_t) siridb_server_cexpr_cb;
-
- qp_add_raw(
- query->packer,
- (const unsigned char *) "servers_selected_points",
- 23);
-
- siridb_server_walker_t wserver = {siridb->server, siridb};
- if (where_expr == NULL || cexpr_run(where_expr, cb, &wserver))
- {
- q_count->n += siridb->selected_points;
- }
-
- if (IS_MASTER)
- {
- siridb_query_forward(
- handle,
- SIRIDB_QUERY_FWD_SERVERS,
- (sirinet_promises_cb) on_count_xxx_response,
- 0);
- }
- else
- {
- qp_add_int64(query->packer, q_count->n);
- SIRIPARSER_ASYNC_NEXT_NODE
- }
-}
-
-static void exit_count_shards(uv_async_t * handle)
-{
- siridb_query_t * query = (siridb_query_t *) handle->data;
- CLIENT_SIRIDB(query->client, siridb)
- query_count_t * q_count = (query_count_t *) query->data;
-
- qp_add_raw(query->packer, (const unsigned char *) "shards", 6);
-
- if (q_count->where_expr == NULL)
- {
- q_count->n = siridb->shards->len;
- }
- else
- {
- uint64_t duration;
- siridb_shard_view_t vshard = {
- .server=siridb->server
- };
- size_t i;
- slist_t * shards_list;
-
- uv_mutex_lock(&siridb->shards_mutex);
-
- shards_list = imap_2slist_ref(siridb->shards);
-
- uv_mutex_unlock(&siridb->shards_mutex);
-
- if (shards_list == NULL)
- {
- MEM_ERR_RET
- }
-
- for (i = 0; i < shards_list->len; i++)
- {
- vshard.shard = (siridb_shard_t *) shards_list->data[i];
-
- /* set start and end properties */
- duration = (vshard.shard->tp == SIRIDB_SHARD_TP_NUMBER) ?
- siridb->duration_num : siridb->duration_log;
- vshard.start = vshard.shard->id - vshard.shard->id % duration;
- vshard.end = vshard.start + duration;
-
- if (cexpr_run(
- q_count->where_expr,
- (cexpr_cb_t) siridb_shard_cexpr_cb,
- &vshard))
- {
- q_count->n++;
- }
-
- siridb_shard_decref(vshard.shard);
- }
-
- slist_free(shards_list);
- }
-
- if (IS_MASTER)
- {
- siridb_query_forward(
- handle,
- SIRIDB_QUERY_FWD_SERVERS,
- (sirinet_promises_cb) on_count_xxx_response,
- 0);
- }
- else
- {
- qp_add_int64(query->packer, q_count->n);
- SIRIPARSER_ASYNC_NEXT_NODE
- }
-}
-
-static void exit_count_shards_size(uv_async_t * handle)
-{
- siridb_query_t * query = (siridb_query_t *) handle->data;
- CLIENT_SIRIDB(query->client, siridb)
- query_count_t * q_count = (query_count_t *) query->data;
- uint64_t duration;
- size_t i;
- slist_t * shards_list;
- siridb_shard_view_t vshard = {
- .server=siridb->server
- };
-
- qp_add_raw(query->packer, (const unsigned char *) "shards_size", 11);
-
- uv_mutex_lock(&siridb->shards_mutex);
-
- shards_list = imap_2slist_ref(siridb->shards);
-
- uv_mutex_unlock(&siridb->shards_mutex);
-
- if (shards_list == NULL)
- {
- MEM_ERR_RET
- }
-
- for (i = 0; i < shards_list->len; i++)
- {
- vshard.shard = (siridb_shard_t *) shards_list->data[i];
-
- /* set start and end properties */
- duration = (vshard.shard->tp == SIRIDB_SHARD_TP_NUMBER) ?
- siridb->duration_num : siridb->duration_log;
- vshard.start = vshard.shard->id - vshard.shard->id % duration;
- vshard.end = vshard.start + duration;
-
- if (q_count->where_expr == NULL || cexpr_run(
- q_count->where_expr,
- (cexpr_cb_t) siridb_shard_cexpr_cb,
- &vshard))
- {
- q_count->n += vshard.shard->len;
- }
-
- siridb_shard_decref(vshard.shard);
- }
-
- slist_free(shards_list);
-
- if (IS_MASTER)
- {
- siridb_query_forward(
- handle,
- SIRIDB_QUERY_FWD_SERVERS,
- (sirinet_promises_cb) on_count_xxx_response,
- 0);
- }
- else
- {
- qp_add_int64(query->packer, q_count->n);
- SIRIPARSER_ASYNC_NEXT_NODE
- }
-}
-
-static void exit_count_users(uv_async_t * handle)
-{
- siridb_query_t * query = (siridb_query_t *) handle->data;
- CLIENT_SIRIDB(query->client, siridb)
- llist_node_t * node = siridb->users->first;
- cexpr_t * where_expr = ((query_count_t *) query->data)->where_expr;
- cexpr_cb_t cb = (cexpr_cb_t) siridb_user_cexpr_cb;
- int n = 0;
-
- qp_add_raw(query->packer, (const unsigned char *) "users", 5);
-
- while (node != NULL)
- {
- if (where_expr == NULL || cexpr_run(where_expr, cb, node->data))
- {
- n++;
- }
- node = node->next;
- }
-
- qp_add_int64(query->packer, n);
-
- SIRIPARSER_ASYNC_NEXT_NODE
-}
-
-static void exit_create_group(uv_async_t * handle)
-{
- siridb_query_t * query = (siridb_query_t *) handle->data;
- CLIENT_SIRIDB(query->client, siridb)
- cleri_node_t * name_nd =
- query->nodes->node->children->next->node;
-
- cleri_node_t * for_nd =
- query->nodes->node->children->next->next->next->node;
-
- MASTER_CHECK_ACCESSIBLE(siridb)
-
- char group_name[name_nd->len - 1];
- strx_extract_string(group_name, name_nd->str, name_nd->len);
-
- if (siridb_groups_add_group(
- siridb->groups,
- group_name,
- for_nd->str,
- for_nd->len,
- query->err_msg))
- {
- siridb_query_send_error(handle, CPROTO_ERR_QUERY);
- }
- else if (siridb_groups_save(siridb->groups))
- {
- snprintf(query->err_msg,
- SIRIDB_MAX_SIZE_ERR_MSG,
- "Cannot write groups to file: %s",
- siridb->groups->fn);
- siridb_query_send_error(handle, CPROTO_ERR_QUERY);
- log_critical("%s", query->err_msg);
- }
- else
- {
-#if DEBUG
- assert (query->packer == NULL);
-#endif
- query->packer = sirinet_packer_new(1024);
- if (query->packer == NULL)
- {
- MEM_ERR_RET
- }
- qp_add_type(query->packer, QP_MAP_OPEN);
-
- QP_ADD_SUCCESS
- log_info(MSG_SUCCESS_CREATE_GROUP, group_name);
- qp_add_fmt_safe(query->packer, MSG_SUCCESS_CREATE_GROUP, group_name);
-
- if (IS_MASTER)
- {
- siridb_query_forward(
- handle,
- SIRIDB_QUERY_FWD_UPDATE,
- (sirinet_promises_cb) on_update_xxx_response,
- 0);
- }
- else
- {
- SIRIPARSER_ASYNC_NEXT_NODE
- }
- }
-}
-
-static void exit_create_user(uv_async_t * handle)
-{
- siridb_query_t * query = (siridb_query_t *) handle->data;
- CLIENT_SIRIDB(query->client, siridb)
- siridb_user_t * user = ((query_alter_t *) query->data)->via.user;
- cleri_node_t * user_node =
- query->nodes->node->children->next->node;
-
-#if DEBUG
- /* both name and packer should be NULL at this point */
- assert(user->name == NULL);
- assert(query->packer == NULL);
-#endif
-
- MASTER_CHECK_ACCESSIBLE(siridb)
-
- char name[user_node->len - 1];
- strx_extract_string(name, user_node->str, user_node->len);
-
- if (siridb_user_set_name(
- siridb,
- user,
- name,
- query->err_msg) ||
- siridb_users_add_user(
- siridb,
- user,
- query->err_msg))
- {
- siridb_query_send_error(handle, CPROTO_ERR_QUERY);
- }
- else
- {
- /* success, increment the user reference counter */
- siridb_user_incref(user);
-
-#if DEBUG
- assert (query->packer == NULL);
-#endif
- query->packer = sirinet_packer_new(1024);
-
- if (query->packer == NULL)
- {
- MEM_ERR_RET
- }
-
- qp_add_type(query->packer, QP_MAP_OPEN);
-
- QP_ADD_SUCCESS
-
- log_info(MSG_SUCCESS_CREATE_USER, user->name);
- qp_add_fmt_safe(query->packer, MSG_SUCCESS_CREATE_USER, user->name);
-
- if (IS_MASTER)
- {
- siridb_query_forward(
- handle,
- SIRIDB_QUERY_FWD_UPDATE,
- (sirinet_promises_cb) on_update_xxx_response,
- 0);
- }
- else
- {
- SIRIPARSER_ASYNC_NEXT_NODE
- }
- }
-}
-
-static void exit_drop_group(uv_async_t * handle)
-{
- siridb_query_t * query = (siridb_query_t *) handle->data;
- CLIENT_SIRIDB(query->client, siridb)
-
- MASTER_CHECK_ACCESSIBLE(siridb)
-
- cleri_node_t * group_node =
- query->nodes->node->children->next->node;
-
- char name[group_node->len - 1];
-
- strx_extract_string(name, group_node->str, group_node->len);
-
- if (siridb_groups_drop_group(siridb->groups, name, query->err_msg))
- {
- siridb_query_send_error(handle, CPROTO_ERR_QUERY);
- }
- else
- {
- QP_ADD_SUCCESS
- log_info(MSG_SUCCESS_DROP_GROUP, name);
- qp_add_fmt_safe(query->packer, MSG_SUCCESS_DROP_GROUP, name);
-
- if (IS_MASTER)
- {
- siridb_query_forward(
- handle,
- SIRIDB_QUERY_FWD_UPDATE,
- (sirinet_promises_cb) on_update_xxx_response,
- 0);
- }
- else
- {
- SIRIPARSER_ASYNC_NEXT_NODE
- }
- }
-}
-
-static void exit_drop_series(uv_async_t * handle)
-{
- siridb_query_t * query = (siridb_query_t *) handle->data;
- CLIENT_SIRIDB(query->client, siridb)
- query_drop_t * q_drop = (query_drop_t *) query->data;
-
- MASTER_CHECK_ACCESSIBLE(siridb)
-
- /*
- * We transform or copy the references from imap to slist because we need
- * this list for both filtering or performing the actual drop.
- */
- uv_mutex_lock(&siridb->series_mutex);
-
- q_drop->slist = (q_drop->series_map == NULL) ?
- imap_2slist_ref(siridb->series_map) :
- imap_slist_pop(q_drop->series_map);
-
- uv_mutex_unlock(&siridb->series_mutex);
-
- if (q_drop->slist == NULL)
- {
- MEM_ERR_RET
- }
-
- if (q_drop->series_map != NULL)
- {
- /* now we can simply destroy the imap in case we had one */
- imap_free(q_drop->series_map, NULL);
- q_drop->series_map = NULL;
- }
-
- /*
- * This function will be called twice when using a where statement.
- * The second time the where_expr is NULL and the reason we do this is
- * so that we can honor a correct drop threshold.
- */
- if (q_drop->where_expr != NULL)
- {
- /* create a new one */
- q_drop->series_map = imap_new();
-
- if (q_drop->series_map == NULL)
- {
- MEM_ERR_RET
- }
-
- uv_async_t * next = (uv_async_t *) malloc(sizeof(uv_async_t));
-
- if (next == NULL)
- {
- MEM_ERR_RET
- }
-
- next->data = handle->data;
-
- uv_async_init(
- siri.loop,
- next,
- (uv_async_cb) async_filter_series);
- uv_async_send(next);
-
- uv_close((uv_handle_t *) handle, (uv_close_cb) free);
-
- }
- else
- {
- double percent = (double)
- q_drop->slist->len / siridb->series_map->len;
-
- if (IS_MASTER &&
- q_drop->slist->len &&
- (~q_drop->flags & QUERIES_IGNORE_DROP_THRESHOLD) &&
- percent >= siridb->drop_threshold)
- {
- snprintf(query->err_msg,
- SIRIDB_MAX_SIZE_ERR_MSG,
- "This query would drop %0.2f%% of the series in pool %u. "
- "Add \'set ignore_threshold true\' to the query "
- "statement if you really want to do this.",
- percent * 100,
- siridb->server->pool);
-
- siridb_query_send_error(handle, CPROTO_ERR_QUERY);
- }
- else
- {
- QP_ADD_SUCCESS
-
- q_drop->n = q_drop->slist->len;
-
- uv_async_t * next = (uv_async_t *) malloc(sizeof(uv_async_t));
-
- if (next == NULL)
- {
- MEM_ERR_RET
- }
-
- next->data = handle->data;
-
- uv_async_init(
- siri.loop,
- next,
- (uv_async_cb) async_drop_series);
- uv_async_send(next);
-
- uv_close((uv_handle_t *) handle, (uv_close_cb) free);
- }
- }
-}
-
-static void exit_drop_server(uv_async_t * handle)
-{
- siridb_query_t * query = (siridb_query_t *) handle->data;
- CLIENT_SIRIDB(query->client, siridb)
- siridb_server_t * server = siridb_server_from_node(
- siridb,
- query->nodes->node->children->next->node->children->node,
- query->err_msg);
-
- MASTER_CHECK_REINDEXING(siridb)
- MASTER_CHECK_ONLINE(siridb)
-
- if (server == NULL)
- {
- siridb_query_send_error(handle, CPROTO_ERR_QUERY);
- }
- else if (siridb->pools->pool[server->pool].len == 1)
- {
- snprintf(
- query->err_msg,
- SIRIDB_MAX_SIZE_ERR_MSG,
- "Cannot remove server '%s' because this is the only "
- "server for pool %u",
- server->name,
- server->pool);
- siridb_query_send_error(handle, CPROTO_ERR_QUERY);
- }
- else if (siridb->server == server || server->socket != NULL)
- {
- snprintf(
- query->err_msg,
- SIRIDB_MAX_SIZE_ERR_MSG,
- "Cannot remove server '%s' because the server is still "
- "online. (stop SiriDB on this server if you really want "
- "to remove the server)",
- server->name);
- siridb_query_send_error(handle, CPROTO_ERR_QUERY);
- }
- else
- {
- QP_ADD_SUCCESS
- log_info(MSG_SUCCESS_DROP_SERVER, server->name);
- qp_add_fmt_safe(query->packer, MSG_SUCCESS_DROP_SERVER, server->name);
-
- if (IS_MASTER)
- {
- query->flags |= SIRIDB_QUERY_FLAG_REBUILD;
- siridb_query_forward(
- handle,
- SIRIDB_QUERY_FWD_UPDATE,
- (sirinet_promises_cb) on_update_xxx_response,
- FLAG_ONLY_CHECK_ONLINE);
- }
- else
- {
- SIRIPARSER_ASYNC_NEXT_NODE
- }
-
- /*
- * After calling this function, all references to the server
- * object might be gone
- */
- if (siridb_server_drop(siridb, server))
- {
- log_critical("Cannot save servers to file");
- }
- }
-}
-
-static void exit_drop_shards(uv_async_t * handle)
-{
- siridb_query_t * query = (siridb_query_t *) handle->data;
- CLIENT_SIRIDB(query->client, siridb)
- query_drop_t * q_drop = (query_drop_t *) query->data;
-
- MASTER_CHECK_ACCESSIBLE(siridb)
-
- uv_mutex_lock(&siridb->shards_mutex);
-
- q_drop->shards_list = imap_2slist_ref(siridb->shards);
-
- uv_mutex_unlock(&siridb->shards_mutex);
-
- if (q_drop->shards_list == NULL)
- {
- MEM_ERR_RET
- }
-
- if (q_drop->where_expr != NULL)
- {
- uint64_t duration;
- siridb_shard_view_t vshard = {
- .server=siridb->server
- };
- size_t dropped = 0;
- size_t i;
-
- for (i = 0; i < q_drop->shards_list->len; i++)
- {
- vshard.shard = (siridb_shard_t *) q_drop->shards_list->data[i];
-
- /* set start and end properties */
- duration = (vshard.shard->tp == SIRIDB_SHARD_TP_NUMBER) ?
- siridb->duration_num : siridb->duration_log;
-
- vshard.start = vshard.shard->id - vshard.shard->id % duration;
- vshard.end = vshard.start + duration;
-
- if (!cexpr_run(
- q_drop->where_expr,
- (cexpr_cb_t) siridb_shard_cexpr_cb,
- &vshard))
- {
- siridb_shard_decref(vshard.shard);
- dropped++;
- }
- else if (dropped)
- {
- q_drop->shards_list->data[i - dropped] = vshard.shard;
- }
- }
-
- q_drop->shards_list->len -= dropped;
- }
-
- double percent = (double)
- q_drop->shards_list->len / siridb->shards->len;
-
- if (IS_MASTER &&
- q_drop->shards_list->len &&
- (~q_drop->flags & QUERIES_IGNORE_DROP_THRESHOLD) &&
- percent >= siridb->drop_threshold)
- {
- snprintf(query->err_msg,
- SIRIDB_MAX_SIZE_ERR_MSG,
- "This query would drop %0.2f%% of the shards in pool %u. "
- "Add \'set ignore_threshold true\' to the query "
- "statement if you really want to do this.",
- percent * 100,
- siridb->server->pool);
-
- siridb_query_send_error(handle, CPROTO_ERR_QUERY);
- }
- else
- {
- uv_async_t * next;
-
- QP_ADD_SUCCESS
-
- q_drop->n = q_drop->shards_list->len;
-
- next = (uv_async_t *) malloc(sizeof(uv_async_t));
-
- if (next == NULL)
- {
- MEM_ERR_RET
- }
-
- next->data = handle->data;
-
- uv_async_init(
- siri.loop,
- next,
- (uv_async_cb) async_drop_shards);
- uv_async_send(next);
-
- uv_close((uv_handle_t *) handle, (uv_close_cb) free);
- }
-}
-
-static void exit_drop_user(uv_async_t * handle)
-{
- siridb_query_t * query = (siridb_query_t *) handle->data;
- CLIENT_SIRIDB(query->client, siridb)
-
- MASTER_CHECK_ACCESSIBLE(siridb)
-
- cleri_node_t * user_node =
- query->nodes->node->children->next->node;
- char username[user_node->len - 1];
-
- strx_extract_string(username, user_node->str, user_node->len);
-
- if (siridb_users_drop_user(
- siridb,
- username,
- query->err_msg))
- {
- siridb_query_send_error(handle, CPROTO_ERR_QUERY);
- }
- else
- {
- QP_ADD_SUCCESS
- log_info(MSG_SUCCESS_DROP_USER, username);
- qp_add_fmt_safe(query->packer, MSG_SUCCESS_DROP_USER, username);
-
- if (IS_MASTER)
- {
- siridb_query_forward(
- handle,
- SIRIDB_QUERY_FWD_UPDATE,
- (sirinet_promises_cb) on_update_xxx_response,
- 0);
- }
- else
- {
- SIRIPARSER_ASYNC_NEXT_NODE
- }
- }
-}
-
-static void exit_grant_user(uv_async_t * handle)
-{
- siridb_query_t * query = (siridb_query_t *) handle->data;
- CLIENT_SIRIDB(query->client, siridb)
-
- if (siridb_users_save(siridb))
- {
- sprintf(query->err_msg, "Could not write users to file!");
- log_critical(query->err_msg);
- siridb_query_send_error(handle, CPROTO_ERR_QUERY);
- return;
- }
-
-#if DEBUG
- assert (query->packer == NULL);
-#endif
-
- query->packer = sirinet_packer_new(1024);
-
- if (query->packer == NULL)
- {
- MEM_ERR_RET
- }
-
- qp_add_type(query->packer, QP_MAP_OPEN);
-
- QP_ADD_SUCCESS
- char * name = ((query_alter_t *) query->data)->via.user->name;
- log_info(MSG_SUCCESS_GRANT_USER, name);
- qp_add_fmt_safe(query->packer, MSG_SUCCESS_GRANT_USER, name);
-
- if (IS_MASTER)
- {
- siridb_query_forward(
- handle,
- SIRIDB_QUERY_FWD_UPDATE,
- (sirinet_promises_cb) on_update_xxx_response,
- 0);
- }
- else
- {
- SIRIPARSER_ASYNC_NEXT_NODE
- }
-}
-
-static void exit_help_xxx(uv_async_t * handle)
-{
- siridb_query_t * query = (siridb_query_t *) handle->data;
-
- if (query->data != NULL)
- {
-#if DEBUG
- assert (query->packer == NULL);
-#endif
- const char * help = siri_help_get(
- query->nodes->node->cl_obj->gid,
- (const char *) query->data,
- query->err_msg);
-
- if (help == NULL)
- {
- siridb_query_send_error(handle, CPROTO_ERR_QUERY);
- return;
- }
-
- query->packer = sirinet_packer_new(4096);
-
- if (query->packer == NULL)
- {
- MEM_ERR_RET
- }
-
- qp_add_type(query->packer, QP_MAP_OPEN);
- qp_add_raw(query->packer, (const unsigned char *) "help", 4);
- qp_add_string(query->packer, help);
-
- free(query->data);
- query->data = NULL;
- }
- SIRIPARSER_ASYNC_NEXT_NODE
-}
-
-static void exit_list_groups(uv_async_t * handle)
-{
- siridb_query_t * query = (siridb_query_t *) handle->data;
- CLIENT_SIRIDB(query->client, siridb)
- query_list_t * q_list = (query_list_t *) query->data;
-
- int is_local = (q_list->props == NULL);
-
- /* if not is_local check for 'remote' columns */
- if (!is_local)
- {
- is_local = 1;
- size_t i;
- for (i = 0; i < q_list->props->len; i++)
- {
- if (siridb_group_is_remote_prop(
- *((uint32_t *) q_list->props->data[i])))
- {
- is_local = 0;
- break;
- }
- }
- }
-
- /* if is_local, check if we use 'remote' props in where expression */
- if (is_local && q_list->where_expr != NULL)
- {
- is_local = !cexpr_contains(
- q_list->where_expr,
- siridb_group_is_remote_prop);
- }
-
- if (is_local)
- {
- finish_list_groups(handle);
- }
- else
- {
- sirinet_pkg_t * pkg = sirinet_pkg_new(0, 0, BPROTO_REQ_GROUPS, NULL);
-
- if (pkg != NULL)
- {
- siri_async_incref(handle);
-
- query->nodes->cb = (uv_async_cb) finish_list_groups;
-
- siridb_pools_send_pkg(
- siridb,
- pkg,
- 0,
- (sirinet_promises_cb) on_groups_response,
- handle,
- 0);
- }
- }
-}
-
-static void exit_list_pools(uv_async_t * handle)
-{
- siridb_query_t * query = (siridb_query_t *) handle->data;
- CLIENT_SIRIDB(query->client, siridb)
- query_list_t * q_list = (query_list_t *) query->data;
- siridb_pool_t * pool = siridb->pools->pool + siridb->server->pool;
- siridb_pool_walker_t wpool = {
- .servers=pool->len,
- .series=siridb->series->len,
- .pool=siridb->server->pool
- };
- uint_fast16_t prop;
- cexpr_t * where_expr = q_list->where_expr;
-
- if (q_list->props == NULL)
- {
- q_list->props = slist_new(3);
-
- if (q_list->props == NULL)
- {
- MEM_ERR_RET
- }
-
- slist_append(q_list->props, &GID_K_POOL);
- slist_append(q_list->props, &GID_K_SERVERS);
- slist_append(q_list->props, &GID_K_SERIES);
- qp_add_raw(query->packer, (const unsigned char *) "pool", 4);
- qp_add_raw(query->packer, (const unsigned char *) "servers", 7);
- qp_add_raw(query->packer, (const unsigned char *) "series", 6);
- }
-
- qp_add_type(query->packer, QP_ARRAY_CLOSE);
-
- qp_add_raw(query->packer, (const unsigned char *) "pools", 5);
- qp_add_type(query->packer, QP_ARRAY_OPEN);
-
- if ( q_list->limit &&
- (where_expr == NULL || cexpr_run(
- where_expr,
- (cexpr_cb_t) siridb_pool_cexpr_cb,
- &wpool)))
- {
- qp_add_type(query->packer, QP_ARRAY_OPEN);
-
- for (prop = 0; prop < q_list->props->len; prop++)
- {
- switch(*((uint32_t *) q_list->props->data[prop]))
- {
- case CLERI_GID_K_POOL:
- qp_add_int16(query->packer, wpool.pool);
- break;
- case CLERI_GID_K_SERVERS:
- qp_add_int16(query->packer, wpool.servers);
- break;
- case CLERI_GID_K_SERIES:
- qp_add_int64(query->packer, wpool.series);
- break;
- }
- }
-
- qp_add_type(query->packer, QP_ARRAY_CLOSE);
- q_list->limit--;
- }
-
- if (IS_MASTER && q_list->limit)
- {
- /* we have not reached the limit, send the query to other pools */
- siridb_query_forward(
- handle,
- SIRIDB_QUERY_FWD_POOLS,
- (sirinet_promises_cb) on_list_xxx_response,
- 0);
- }
- else
- {
- qp_add_type(query->packer, QP_ARRAY_CLOSE);
-
- SIRIPARSER_ASYNC_NEXT_NODE
- }
-}
-
-static void exit_list_series(uv_async_t * handle)
-{
- siridb_query_t * query = (siridb_query_t *) handle->data;
- query_list_t * q_list = (query_list_t *) query->data;
- CLIENT_SIRIDB(query->client, siridb)
-
- if (q_list->props == NULL)
- {
- q_list->props = slist_new(1);
-
- if (q_list->props == NULL)
- {
- MEM_ERR_RET
- }
-
- slist_append(q_list->props, &GID_K_NAME);
- qp_add_raw(query->packer, (const unsigned char *) "name", 4);
- }
-
- qp_add_type(query->packer, QP_ARRAY_CLOSE);
-
- qp_add_raw(query->packer, (const unsigned char *) "series", 6);
- qp_add_type(query->packer, QP_ARRAY_OPEN);
-
- uv_mutex_lock(&siridb->series_mutex);
-
- q_list->slist = imap_2slist_ref((q_list->series_map == NULL) ?
- siridb->series_map : q_list->series_map);
-
- uv_mutex_unlock(&siridb->series_mutex);
-
- if (q_list->slist == NULL)
- {
- MEM_ERR_RET;
- }
-
- uv_async_t * next = (uv_async_t *) malloc(sizeof(uv_async_t));
-
- if (next == NULL)
- {
- MEM_ERR_RET
- }
-
- next->data = handle->data;
-
- uv_async_init(
- siri.loop,
- next,
- (uv_async_cb) async_list_series);
- uv_async_send(next);
-
- uv_close((uv_handle_t *) handle, (uv_close_cb) free);
-}
-
-static void exit_list_servers(uv_async_t * handle)
-{
- siridb_query_t * query = (siridb_query_t *) handle->data;
- CLIENT_SIRIDB(query->client, siridb)
-
- query_list_t * q_list = (query_list_t *) query->data;
- cexpr_t * where_expr = q_list->where_expr;
- int is_local = IS_MASTER;
-
- /* if is_local, check if we need ask for 'remote' columns */
- if (is_local && q_list->props != NULL)
- {
- size_t i;
- for (i = 0; i < q_list->props->len; i++)
- {
- if (siridb_server_is_remote_prop(
- *((uint32_t *) q_list->props->data[i])))
- {
- is_local = 0;
- break;
- }
- }
- }
-
- /* if is_local, check if we use 'remote' props in where expression */
- if (is_local && where_expr != NULL)
- {
- is_local = !cexpr_contains(where_expr, siridb_server_is_remote_prop);
- }
-
- if (q_list->props == NULL)
- {
- q_list->props = slist_new(5);
-
- if (q_list->props == NULL)
- {
- MEM_ERR_RET
- }
-
- slist_append(q_list->props, &GID_K_NAME);
- slist_append(q_list->props, &GID_K_POOL);
- slist_append(q_list->props, &GID_K_VERSION);
- slist_append(q_list->props, &GID_K_ONLINE);
- slist_append(q_list->props, &GID_K_STATUS);
- qp_add_raw(query->packer, (const unsigned char *) "name", 4);
- qp_add_raw(query->packer, (const unsigned char *) "pool", 4);
- qp_add_raw(query->packer, (const unsigned char *) "version", 7);
- qp_add_raw(query->packer, (const unsigned char *) "online", 6);
- qp_add_raw(query->packer, (const unsigned char *) "status", 6);
- }
-
- qp_add_type(query->packer, QP_ARRAY_CLOSE);
-
- qp_add_raw(query->packer, (const unsigned char *) "servers", 7);
- qp_add_type(query->packer, QP_ARRAY_OPEN);
-
- if (is_local)
- {
- llist_walkn(
- siridb->servers,
- &q_list->limit,
- (llist_cb) siridb_servers_list,
- handle);
- }
- else
- {
- q_list->limit -= siridb_servers_list(siridb->server, handle);
- }
-
-
- if (IS_MASTER && !is_local && q_list->limit)
- {
- siridb_query_forward(
- handle,
- SIRIDB_QUERY_FWD_SERVERS,
- (sirinet_promises_cb) on_list_xxx_response,
- 0);
- }
- else
- {
- qp_add_type(query->packer, QP_ARRAY_CLOSE);
- SIRIPARSER_ASYNC_NEXT_NODE
- }
-}
-
-static void exit_list_shards(uv_async_t * handle)
-{
- siridb_query_t * query = (siridb_query_t *) handle->data;
- CLIENT_SIRIDB(query->client, siridb)
-
- query_list_t * q_list = (query_list_t *) query->data;
- uint_fast16_t prop;
- uint64_t duration;
- cexpr_t * where_expr = q_list->where_expr;
- siridb_shard_view_t vshard = {
- .server=siridb->server
- };
- size_t i;
- slist_t * shards_list;
-
- uv_mutex_lock(&siridb->shards_mutex);
-
- shards_list = imap_2slist_ref(siridb->shards);
-
- uv_mutex_unlock(&siridb->shards_mutex);
-
- if (shards_list == NULL)
- {
- MEM_ERR_RET
- }
-
- if (q_list->props == NULL)
- {
- q_list->props = slist_new(5);
-
- if (q_list->props == NULL)
- {
- MEM_ERR_RET
- }
-
- slist_append(q_list->props, &GID_K_SID);
- slist_append(q_list->props, &GID_K_POOL);
- slist_append(q_list->props, &GID_K_SERVER);
- slist_append(q_list->props, &GID_K_START);
- slist_append(q_list->props, &GID_K_END);
- qp_add_raw(query->packer, (const unsigned char *) "sid", 3);
- qp_add_raw(query->packer, (const unsigned char *) "pool", 4);
- qp_add_raw(query->packer, (const unsigned char *) "server", 6);
- qp_add_raw(query->packer, (const unsigned char *) "start", 5);
- qp_add_raw(query->packer, (const unsigned char *) "end", 3);
- }
-
- qp_add_type(query->packer, QP_ARRAY_CLOSE);
-
- qp_add_raw(query->packer, (const unsigned char *) "shards", 6);
- qp_add_type(query->packer, QP_ARRAY_OPEN);
-
- for (i = 0; i < shards_list->len; i++)
- {
- vshard.shard = (siridb_shard_t *) shards_list->data[i];
-
- /* set start and end properties */
- duration = (vshard.shard->tp == SIRIDB_SHARD_TP_NUMBER) ?
- siridb->duration_num : siridb->duration_log;
- vshard.start = vshard.shard->id - vshard.shard->id % duration;
- vshard.end = vshard.start + duration;
-
- if (q_list->limit && (where_expr == NULL || cexpr_run(
- where_expr,
- (cexpr_cb_t) siridb_shard_cexpr_cb,
- &vshard)))
- {
- qp_add_type(query->packer, QP_ARRAY_OPEN);
-
- for (prop = 0; prop < q_list->props->len; prop++)
- {
- switch(*((uint32_t *) q_list->props->data[prop]))
- {
- case CLERI_GID_K_SID:
- qp_add_int64(query->packer, vshard.shard->id);
- break;
- case CLERI_GID_K_POOL:
- qp_add_int16(query->packer, vshard.server->pool);
- break;
- case CLERI_GID_K_SIZE:
- qp_add_int64(query->packer, vshard.shard->len);
- break;
- case CLERI_GID_K_START:
- qp_add_int64(query->packer, vshard.start);
- break;
- case CLERI_GID_K_END:
- qp_add_int64(query->packer, vshard.end);
- break;
- case CLERI_GID_K_TYPE:
- qp_add_string(
- query->packer,
- shard_type_map[vshard.shard->tp]);
- break;
- case CLERI_GID_K_SERVER:
- qp_add_string(query->packer, vshard.server->name);
- break;
- case CLERI_GID_K_STATUS:
- {
- char buffer[SIRIDB_SHARD_STATUS_STR_MAX];
- int n = siridb_shard_status(buffer, vshard.shard);
- qp_add_raw(
- query->packer,
- (const unsigned char *) buffer,
- n);
- }
- break;
- }
- }
- qp_add_type(query->packer, QP_ARRAY_CLOSE);
-
- q_list->limit--;
- }
-
- siridb_shard_decref(vshard.shard);
- }
-
- slist_free(shards_list);
-
- if (IS_MASTER && q_list->limit)
- {
- /* we have not reached the limit, send the query to other pools */
- siridb_query_forward(
- handle,
- SIRIDB_QUERY_FWD_SERVERS,
- (sirinet_promises_cb) on_list_xxx_response,
- 0);
- }
- else
- {
- qp_add_type(query->packer, QP_ARRAY_CLOSE);
-
- SIRIPARSER_ASYNC_NEXT_NODE
- }
-}
-
-static void exit_list_users(uv_async_t * handle)
-{
- siridb_query_t * query = (siridb_query_t *) handle->data;
- CLIENT_SIRIDB(query->client, siridb)
-
- llist_node_t * node = siridb->users->first;
- slist_t * props = ((query_list_t *) query->data)->props;
- cexpr_cb_t cb = (cexpr_cb_t) siridb_user_cexpr_cb;
- query_list_t * q_list = (query_list_t *) query->data;
- cexpr_t * where_expr = q_list->where_expr;
- size_t i;
- siridb_user_t * user;
-
- if (props == NULL)
- {
- qp_add_raw(query->packer, (const unsigned char *) "name", 4);
- qp_add_raw(query->packer, (const unsigned char *) "access", 6);
- }
-
- qp_add_type(query->packer, QP_ARRAY_CLOSE);
-
- qp_add_raw(query->packer, (const unsigned char *) "users", 5);
- qp_add_type(query->packer, QP_ARRAY_OPEN);
-
- while (node != NULL && q_list->limit)
- {
- user = node->data;
-
- if (where_expr == NULL || cexpr_run(where_expr, cb, user))
- {
- q_list->limit--;
-
- qp_add_type(query->packer, QP_ARRAY_OPEN);
-
- if (props == NULL)
- {
- siridb_user_prop(user, query->packer, CLERI_GID_K_NAME);
- siridb_user_prop(user, query->packer, CLERI_GID_K_ACCESS);
- }
- else
- {
- for (i = 0; i < props->len; i++)
- {
- siridb_user_prop(
- user,
- query->packer,
- *((uint32_t *) props->data[i]));
- }
- }
-
- qp_add_type(query->packer, QP_ARRAY_CLOSE);
-
- }
- node = node->next;
- }
- qp_add_type(query->packer, QP_ARRAY_CLOSE);
-
- SIRIPARSER_ASYNC_NEXT_NODE
-}
-
-static void exit_revoke_user(uv_async_t * handle)
-{
- siridb_query_t * query = (siridb_query_t *) handle->data;
- CLIENT_SIRIDB(query->client, siridb)
-
- if (siridb_users_save(siridb))
- {
- sprintf(query->err_msg, "Could not write users to file!");
- log_critical(query->err_msg);
- siridb_query_send_error(handle, CPROTO_ERR_QUERY);
- return;
- }
-
-#if DEBUG
- assert (query->packer == NULL);
-#endif
-
- query->packer = sirinet_packer_new(1024);
-
- if (query->packer == NULL)
- {
- MEM_ERR_RET
- }
-
- qp_add_type(query->packer, QP_MAP_OPEN);
-
- QP_ADD_SUCCESS
- char * name = ((query_alter_t *) query->data)->via.user->name;
- log_info(MSG_SUCCESS_REVOKE_USER, name);
- qp_add_fmt_safe(query->packer, MSG_SUCCESS_REVOKE_USER, name);
-
- if (IS_MASTER)
- {
- siridb_query_forward(
- handle,
- SIRIDB_QUERY_FWD_UPDATE,
- (sirinet_promises_cb) on_update_xxx_response,
- 0);
- }
- else
- {
- SIRIPARSER_ASYNC_NEXT_NODE
- }
-}
-
-static void exit_series_match(uv_async_t * handle)
-{
- siridb_query_t * query = (siridb_query_t *) handle->data;
- query_wrapper_t * q_wrapper = (query_wrapper_t *) query->data;
-
- if (q_wrapper->tp == QUERIES_SELECT)
- {
- query_select_t * q_select = (query_select_t *) q_wrapper;
- if ((q_select->flags & QUERIES_SKIP_GET_POINTS) &&
- (q_select->start_ts != NULL || q_select->end_ts != NULL))
- {
- q_select->flags &= ~QUERIES_SKIP_GET_POINTS;
- }
-
- if ((~q_select->flags & QUERIES_SKIP_GET_POINTS) &&
- q_select->nselects > 1)
- {
- /* We have more than one select request, let's use points caching.
- * (Not critical, everything works if points_map is NULL) */
- q_select->points_map = imap_new();
- }
- }
-
- SIRIPARSER_ASYNC_NEXT_NODE
-}
-
-static void exit_select_aggregate(uv_async_t * handle)
-{
- siridb_query_t * query = (siridb_query_t *) handle->data;
- query_select_t * q_select = (query_select_t *) query->data;
-
- if (q_select->where_expr != NULL)
- {
- /* we transform the references from imap to slist */
- q_select->slist = imap_slist_pop(q_select->series_map);
-
- if (q_select->slist == NULL)
- {
- MEM_ERR_RET
- }
-
- /* now we can simply destroy the imap */
- imap_free(q_select->series_map, NULL);
-
- /* create a new one */
- q_select->series_map = imap_new();
-
- if (q_select->series_map == NULL)
- {
- MEM_ERR_RET
- }
-
- uv_async_t * next =
- (uv_async_t *) malloc(sizeof(uv_async_t));
-
- if (next == NULL)
- {
- MEM_ERR_RET
- }
-
- next->data = handle->data;
-
- uv_async_init(
- siri.loop,
- next,
- (uv_async_cb) async_filter_series);
- uv_async_send(next);
-
- uv_close((uv_handle_t *) handle, (uv_close_cb) free);
-
- }
- else if (siridb_presuf_add(&q_select->presuf, query->nodes->node) == NULL)
- {
- MEM_ERR_RET
- }
- else
- {
- q_select->nselects--;
-
- if (!siridb_presuf_is_unique(q_select->presuf))
- {
- snprintf(query->err_msg,
- SIRIDB_MAX_SIZE_ERR_MSG,
- "When using multiple select methods, add a prefix "
- "and/or suffix to the selection to make them unique.");
- siridb_query_send_error(handle, CPROTO_ERR_QUERY);
- }
- else
- {
- if (q_select->merge_as != NULL)
- {
- slist_t * plist = slist_new(SLIST_DEFAULT_SIZE);
-
- if (plist == NULL || ct_add(
- q_select->result,
- siridb_presuf_name(
- q_select->presuf,
- q_select->merge_as,
- strlen(q_select->merge_as)),
- plist))
- {
- sprintf(query->err_msg,
- "Error while merging points. Make sure the "
- "destination series name is valid.");
- slist_free(plist);
- siridb_query_send_error(handle, CPROTO_ERR_QUERY);
- return;
- }
- }
-
- if (q_select->series_map->len)
- {
- q_select->alist = siridb_aggregate_list(
- query->nodes->node->children->node->children,
- query->err_msg);
- if (q_select->alist == NULL)
- {
- siridb_query_send_error(handle, CPROTO_ERR_QUERY);
- return;
- }
- q_select->slist = imap_2slist_ref(q_select->series_map);
-
- if (q_select->slist == NULL)
- {
- MEM_ERR_RET
- }
-
- uv_async_t * next =
- (uv_async_t *) malloc(sizeof(uv_async_t));
-
- if (next == NULL)
- {
- MEM_ERR_RET
- }
-
- next->data = handle->data;
-
- uv_async_init(
- siri.loop,
- next,
- (uv_async_cb) (
- (q_select->flags & QUERIES_SKIP_GET_POINTS) ?
- async_no_points_aggregate :
- async_select_aggregate));
- uv_async_send(next);
-
- uv_close((uv_handle_t *) handle, (uv_close_cb) free);
- }
- else
- {
- SIRIPARSER_ASYNC_NEXT_NODE
- }
- }
- }
-}
-
-static void exit_select_stmt(uv_async_t * handle)
-{
- siridb_query_t * query = (siridb_query_t *) handle->data;
- query_select_t * q_select = (query_select_t *) query->data;
-
- if (IS_MASTER)
- {
- if (q_select->pmap == NULL || q_select->pmap->len)
- {
- /* we have not reached the limit, send the query to other pools */
- siridb_query_forward(
- handle,
- (q_select->pmap == NULL) ?
- SIRIDB_QUERY_FWD_POOLS :
- SIRIDB_QUERY_FWD_SOME_POOLS,
- (sirinet_promises_cb) on_select_response,
- 0);
- }
- else
- {
- uv_work_t * work = (uv_work_t *) malloc(sizeof(uv_work_t));
- if (work == NULL)
- {
- MEM_ERR_RET
- }
-
- uv_async_t * next = (uv_async_t *) malloc(sizeof(uv_async_t));
- if (next == NULL)
- {
- free(work);
- MEM_ERR_RET
- }
-
- uv_close((uv_handle_t *) handle, (uv_close_cb) free);
-
- handle = next;
- handle->data = query;
- siridb_nodes_next(&query->nodes);
-
- uv_async_init(
- siri.loop,
- handle,
- (query->nodes == NULL) ?
- (uv_async_cb) siridb_send_query_result :
- (uv_async_cb) query->nodes->cb);
-
- siri_async_incref(handle);
- work->data = handle;
- uv_queue_work(
- siri.loop,
- work,
- &master_select_work,
- &master_select_work_finish);
- }
- }
- else
- {
- if (qp_add_raw(query->packer, (const unsigned char *) "select", 6) ||
- qp_add_type(query->packer, QP_MAP_OPEN) ||
- ct_items(
- q_select->result,
- (q_select->merge_as == NULL) ?
- (ct_item_cb) &items_select_other
- :
- (ct_item_cb) &items_select_other_merge,
- handle) ||
- qp_add_type(query->packer, QP_MAP_CLOSE))
- {
- MEM_ERR_RET
- }
- else
- {
- SIRIPARSER_ASYNC_NEXT_NODE
- }
- }
-}
-
-static void exit_set_address(uv_async_t * handle)
-{
- siridb_query_t * query = (siridb_query_t *) handle->data;
- siridb_server_t * server = ((query_alter_t *) query->data)->via.server;
- cleri_node_t * node = query->nodes->node->children->next->next->node;
- CLIENT_SIRIDB(query->client, siridb)
-
- if (siridb->server == server || server->socket != NULL)
- {
- sprintf(query->err_msg, MSG_ERR_SERVER_ADDRESS);
- siridb_query_send_error(handle, CPROTO_ERR_QUERY);
- return;
- }
-
- char address[node->len - 1];
- strx_extract_string(address, node->str, node->len);
-
- int rc;
- rc = siridb_server_update_address(siridb, server, address, server->port);
- switch (rc)
- {
- case -1:
- sprintf(query->err_msg, "Error while updating server address");
- siridb_query_send_error(handle, CPROTO_ERR_QUERY);
- break;
-
- case 0:
- snprintf(query->err_msg,
- SIRIDB_MAX_SIZE_ERR_MSG,
- "Server address is already set to '%s'",
- server->address);
- siridb_query_send_error(handle, CPROTO_ERR_QUERY);
- break;
-
- case 1:
- QP_ADD_SUCCESS
- qp_add_fmt_safe(query->packer,
- MSG_SUCCESS_SET_ADDR_PORT,
- server->name);
- SIRIPARSER_ASYNC_NEXT_NODE
- break;
- }
-}
-
-static void exit_set_backup_mode(uv_async_t * handle)
-{
- siridb_query_t * query = (siridb_query_t *) handle->data;
- CLIENT_SIRIDB(query->client, siridb)
-
-#if DEBUG
- assert (query->data != NULL);
- assert (IS_MASTER);
-#endif
-
- siridb_server_t * server = ((query_alter_t *) query->data)->via.server;
-
- int backup_mode = query->nodes->node->children->next->next->node->
- children->node->cl_obj->gid == CLERI_GID_K_TRUE;
-
- if (backup_mode ^ ((server->flags & SERVER_FLAG_BACKUP_MODE) != 0))
- {
- QP_ADD_SUCCESS
- qp_add_fmt_safe(query->packer,
- MSG_SUCCES_SET_BACKUP_MODE,
- (backup_mode) ? "enabled" : "disabled",
- server->name);
-
- if (server == siridb->server)
- {
- if (backup_mode)
- {
- if (siri_backup_enable(&siri, siridb))
- {
- MEM_ERR_RET
- }
- }
- else
- {
- if (siri_backup_disable(&siri, siridb))
- {
- MEM_ERR_RET
- }
- }
-
- SIRIPARSER_ASYNC_NEXT_NODE
- }
- else
- {
- if (siridb_server_is_online(server))
- {
- sirinet_pkg_t * pkg = sirinet_pkg_new(
- 0,
- 0,
- (backup_mode) ?
- BPROTO_ENABLE_BACKUP_MODE :
- BPROTO_DISABLE_BACKUP_MODE,
- NULL);
-
- if (pkg == NULL)
- {
- MEM_ERR_RET
- }
-
- /* handle will be bound to a timer so we should increment */
- siri_async_incref(handle);
-
- if (siridb_server_send_pkg(
- server,
- pkg,
- 0,
- on_ack_response,
- handle,
- 0))
- {
- /*
- * signal is raised and 'on_ack_response' will not be
- * called
- */
- free(pkg);
- siri_async_decref(&handle);
- MEM_ERR_RET
- }
- }
- else
- {
- snprintf(query->err_msg,
- SIRIDB_MAX_SIZE_ERR_MSG,
- "Cannot %s backup mode, '%s' is currently unavailable",
- (backup_mode) ? "enable" : "disable",
- server->name);
- siridb_query_send_error(handle, CPROTO_ERR_QUERY);
- }
- }
- }
- else
- {
- snprintf(query->err_msg,
- SIRIDB_MAX_SIZE_ERR_MSG,
- "Backup mode is already %s on '%s'.",
- (backup_mode) ? "enabled" : "disabled",
- server->name);
- siridb_query_send_error(handle, CPROTO_ERR_QUERY);
- }
-}
-
-static void exit_set_drop_threshold(uv_async_t * handle)
-{
- siridb_query_t * query = (siridb_query_t *) handle->data;
- CLIENT_SIRIDB(query->client, siridb)
-
- MASTER_CHECK_ACCESSIBLE(siridb)
-
- cleri_node_t * node = query->nodes->node->children->next->next->node;
-
- double drop_threshold = strx_to_double(node->str, node->len);
-
- if (drop_threshold < 0.0 || drop_threshold > 1.0)
- {
- snprintf(query->err_msg,
- SIRIDB_MAX_SIZE_ERR_MSG,
- "Drop threshold should be a value between or "
- "equal to 0 and 1.0 but got %0.3f",
- drop_threshold);
- siridb_query_send_error(handle, CPROTO_ERR_QUERY);
- }
- else
- {
- double old = siridb->drop_threshold;
- siridb->drop_threshold = drop_threshold;
- if (siridb_save(siridb))
- {
- snprintf(query->err_msg,
- SIRIDB_MAX_SIZE_ERR_MSG,
- "Error while saving database changes!");
- siridb_query_send_error(handle, CPROTO_ERR_QUERY);
- }
- else
- {
- QP_ADD_SUCCESS
-
- log_info(
- MSG_SUCCESS_SET_DROP_THRESHOLD,
- old,
- siridb->drop_threshold);
-
- qp_add_fmt_safe(query->packer,
- MSG_SUCCESS_SET_DROP_THRESHOLD,
- old,
- siridb->drop_threshold);
-
- if (IS_MASTER)
- {
- siridb_query_forward(
- handle,
- SIRIDB_QUERY_FWD_UPDATE,
- (sirinet_promises_cb) on_update_xxx_response,
- 0);
- }
- else
- {
- SIRIPARSER_ASYNC_NEXT_NODE
- }
- }
- }
-}
-
-static void exit_set_list_limit(uv_async_t * handle)
-{
- siridb_query_t * query = (siridb_query_t *) handle->data;
- CLIENT_SIRIDB(query->client, siridb)
-
- MASTER_CHECK_ACCESSIBLE(siridb)
- MASTER_CHECK_VERSION(siridb, "2.0.17")
-
- cleri_node_t * node = query->nodes->node->children->next->next->node;
-
- uint64_t limit = strx_to_uint64(node->str, node->len);
-
- if (limit < 1000 || limit >= 4294967296)
- {
- snprintf(query->err_msg,
- SIRIDB_MAX_SIZE_ERR_MSG,
- "List limit should be a value greater than or equal to 1000 "
- "and smaller than 4294967296 but got %" PRIu64,
- limit);
- siridb_query_send_error(handle, CPROTO_ERR_QUERY);
- }
- else
- {
- uint32_t old = siridb->list_limit;
- siridb->list_limit = (uint32_t) limit;
-
- if (siridb_save(siridb))
- {
- snprintf(query->err_msg,
- SIRIDB_MAX_SIZE_ERR_MSG,
- "Error while saving database changes!");
- siridb_query_send_error(handle, CPROTO_ERR_QUERY);
- }
- else
- {
- QP_ADD_SUCCESS
-
- log_info(
- MSG_SUCCESS_SET_LIST_LIMIT,
- old,
- siridb->list_limit);
-
- qp_add_fmt_safe(query->packer,
- MSG_SUCCESS_SET_LIST_LIMIT,
- old,
- siridb->list_limit);
-
- if (IS_MASTER)
- {
- siridb_query_forward(
- handle,
- SIRIDB_QUERY_FWD_UPDATE,
- (sirinet_promises_cb) on_update_xxx_response,
- 0);
- }
- else
- {
- SIRIPARSER_ASYNC_NEXT_NODE
- }
- }
- }
-}
-
-static void exit_set_log_level(uv_async_t * handle)
-{
- siridb_query_t * query = (siridb_query_t *) handle->data;
- query_alter_t * q_alter = (query_alter_t *) query->data;
- CLIENT_SIRIDB(query->client, siridb)
-
-#if DEBUG
- assert (query->data != NULL);
-#endif
-
- cleri_node_t * node =
- query->nodes->node->children->next->next->node->children->node;
-
- int log_level;
-
- switch (node->cl_obj->gid)
- {
- case CLERI_GID_K_DEBUG:
- log_level = LOGGER_DEBUG;
- break;
- case CLERI_GID_K_INFO:
- log_level = LOGGER_INFO;
- break;
- case CLERI_GID_K_WARNING:
- log_level = LOGGER_WARNING;
- break;
- case CLERI_GID_K_ERROR:
- log_level = LOGGER_ERROR;
- break;
- case CLERI_GID_K_CRITICAL:
- log_level = LOGGER_CRITICAL;
- break;
- default:
- assert (0);
- break;
- }
-
- if (q_alter->alter_tp == QUERY_ALTER_SERVERS)
- {
- /*
- * alter_servers
- */
- cexpr_t * where_expr = ((query_list_t *) query->data)->where_expr;
- siridb_server_walker_t wserver = {
- .server=siridb->server,
- .siridb=siridb
- };
-
- if (where_expr == NULL || cexpr_run(
- where_expr,
- (cexpr_cb_t) siridb_server_cexpr_cb,
- &wserver))
- {
- logger_set_level(log_level);
- q_alter->n++;
- }
-
- if (IS_MASTER)
- {
- /*
- * Hide log level information so we can later create an appropriate
- * message.
- */
- q_alter->n += log_level << 16;
- siridb_query_forward(
- handle,
- SIRIDB_QUERY_FWD_SERVERS,
- (sirinet_promises_cb) on_alter_xxx_response,
- 0);
- }
- else
- {
- qp_add_raw(query->packer, (const unsigned char *) "servers", 7);
- qp_add_int64(query->packer, q_alter->n);
- SIRIPARSER_ASYNC_NEXT_NODE
- }
- }
- else
- {
- /*
- * alter_server
- *
- * we can set the success message, we just ignore the message in case
- * an error occurs.
- */
- siridb_server_t * server = q_alter->via.server;
-
- QP_ADD_SUCCESS
- qp_add_fmt_safe(query->packer,
- MSG_SUCCES_SET_LOG_LEVEL,
- logger_level_name(log_level),
- server->name);
-
- if (server == siridb->server)
- {
- logger_set_level(log_level);
-
- SIRIPARSER_ASYNC_NEXT_NODE
- }
- else
- {
- QP_PACK_INT16(buffer, log_level)
-
- if (siridb_server_is_online(server))
- {
- sirinet_pkg_t * pkg = sirinet_pkg_new(
- 0,
- 3,
- BPROTO_LOG_LEVEL_UPDATE,
- buffer);
- if (pkg != NULL)
- {
- /* handle will be bound to a timer so we should increment */
- siri_async_incref(handle);
- if (siridb_server_send_pkg(
- server,
- pkg,
- 0,
- on_ack_response,
- handle,
- 0))
- {
- /*
- * signal is raised and 'on_ack_response' will not be
- * called
- */
- free(pkg);
- siri_async_decref(&handle);
- }
- }
- }
- else
- {
- snprintf(query->err_msg,
- SIRIDB_MAX_SIZE_ERR_MSG,
- "Cannot set log level, '%s' is currently unavailable",
- server->name);
- siridb_query_send_error(handle, CPROTO_ERR_QUERY);
- }
- }
- }
-}
-
-static void exit_set_port(uv_async_t * handle)
-{
- siridb_query_t * query = (siridb_query_t *) handle->data;
- siridb_server_t * server = ((query_alter_t *) query->data)->via.server;
- cleri_node_t * node = query->nodes->node->children->next->next->node;
- CLIENT_SIRIDB(query->client, siridb)
-
- if (siridb->server == server || server->socket != NULL)
- {
- sprintf(query->err_msg, MSG_ERR_SERVER_ADDRESS);
- siridb_query_send_error(handle, CPROTO_ERR_QUERY);
- return;
- }
-
-
- uint64_t port = strx_to_uint64(node->str, node->len);
-
- if (port > 65535)
- {
- sprintf(query->err_msg,
- "Server port must be a value between 0 and 65535");
- siridb_query_send_error(handle, CPROTO_ERR_QUERY);
- }
- else
- {
- int rc;
- rc = siridb_server_update_address(siridb, server, server->address, port);
- switch (rc)
- {
- case -1:
- sprintf(query->err_msg, "Error while updating server address");
- siridb_query_send_error(handle, CPROTO_ERR_QUERY);
- break;
-
- case 0:
- snprintf(query->err_msg,
- SIRIDB_MAX_SIZE_ERR_MSG,
- "Server port is already set to '%u'",
- server->port);
- siridb_query_send_error(handle, CPROTO_ERR_QUERY);
- break;
-
- case 1:
- QP_ADD_SUCCESS
- qp_add_fmt_safe(query->packer,
- MSG_SUCCESS_SET_ADDR_PORT,
- server->name);
- SIRIPARSER_ASYNC_NEXT_NODE
- break;
- }
- }
-}
-
-static void exit_set_select_points_limit(uv_async_t * handle)
-{
- siridb_query_t * query = (siridb_query_t *) handle->data;
- CLIENT_SIRIDB(query->client, siridb)
-
- MASTER_CHECK_ACCESSIBLE(siridb)
- MASTER_CHECK_VERSION(siridb, "2.0.17")
-
- cleri_node_t * node = query->nodes->node->children->next->next->node;
-
- uint64_t limit = strx_to_uint64(node->str, node->len);
-
- if (limit < 1 || limit >= 4294967296)
- {
- snprintf(query->err_msg,
- SIRIDB_MAX_SIZE_ERR_MSG,
- "Select points limit should be a value greater than 0 "
- "and smaller than 4294967296 but got %" PRIu64,
- limit);
- siridb_query_send_error(handle, CPROTO_ERR_QUERY);
- }
- else
- {
- uint32_t old = siridb->select_points_limit;
- siridb->select_points_limit = (uint32_t) limit;
-
- if (siridb_save(siridb))
- {
- snprintf(query->err_msg,
- SIRIDB_MAX_SIZE_ERR_MSG,
- "Error while saving database changes!");
- siridb_query_send_error(handle, CPROTO_ERR_QUERY);
- }
- else
- {
- QP_ADD_SUCCESS
-
- log_info(
- MSG_SUCCESS_SET_SELECT_POINTS_LIMIT,
- old,
- siridb->select_points_limit);
-
- qp_add_fmt_safe(query->packer,
- MSG_SUCCESS_SET_SELECT_POINTS_LIMIT,
- old,
- siridb->select_points_limit);
-
- if (IS_MASTER)
- {
- siridb_query_forward(
- handle,
- SIRIDB_QUERY_FWD_UPDATE,
- (sirinet_promises_cb) on_update_xxx_response,
- 0);
- }
- else
- {
- SIRIPARSER_ASYNC_NEXT_NODE
- }
- }
- }
-}
-
-static void exit_set_timezone(uv_async_t * handle)
-{
- siridb_query_t * query = (siridb_query_t *) handle->data;
- cleri_node_t * node = query->nodes->node->children->next->next->node;
- CLIENT_SIRIDB(query->client, siridb)
-
- MASTER_CHECK_ACCESSIBLE(siridb)
-
- char timezone[node->len - 1];
- strx_extract_string(timezone, node->str, node->len);
-
- iso8601_tz_t new_tz = iso8601_tz(timezone);
-
- if (new_tz < 0)
- {
- snprintf(query->err_msg,
- SIRIDB_MAX_SIZE_ERR_MSG,
- "Unknown time zone: '%s'. (see 'help timezones' "
- "for a list of valid time zones)",
- timezone);
- siridb_query_send_error(handle, CPROTO_ERR_QUERY);
-
- }
- else if (siridb->tz == new_tz)
- {
- snprintf(query->err_msg,
- SIRIDB_MAX_SIZE_ERR_MSG,
- "Database '%s' is already set to time-zone '%s'.",
- siridb->dbname,
- timezone);
- siridb_query_send_error(handle, CPROTO_ERR_QUERY);
- }
- else
- {
- QP_ADD_SUCCESS
-
- qp_add_fmt_safe(
- query->packer,
- MSG_SUCCES_SET_TIMEZONE,
- iso8601_tzname(siridb->tz),
- iso8601_tzname(new_tz));
-
- siridb->tz = new_tz;
-
- if (siridb_save(siridb))
- {
- log_critical("Could not save database changes (database: '%s')",
- siridb->dbname);
- }
-
- if (IS_MASTER)
- {
- siridb_query_forward(
- handle,
- SIRIDB_QUERY_FWD_UPDATE,
- (sirinet_promises_cb) on_update_xxx_response,
- 0);
- }
- else
- {
- SIRIPARSER_ASYNC_NEXT_NODE
- }
- }
-}
-
-static void exit_show_stmt(uv_async_t * handle)
-{
- siridb_query_t * query = (siridb_query_t *) handle->data;
- CLIENT_SIRIDB(query->client, siridb)
- CLIENT_USER(query->client, siridb_user)
- SIRIPARSER_MASTER_CHECK_ACCESS(siridb_user, SIRIDB_ACCESS_SHOW)
-
- cleri_children_t * children =
- query->nodes->node->children->next->node->children;
- siridb_props_cb prop_cb;
-
-#if DEBUG
- assert (query->packer == NULL);
-#endif
-
- query->packer = sirinet_packer_new(4096);
-
- if (query->packer == NULL)
- {
- MEM_ERR_RET
- }
-
- qp_add_type(query->packer, QP_MAP_OPEN);
- qp_add_raw(query->packer, (const unsigned char *) "data", 4);
- qp_add_type(query->packer, QP_ARRAY_OPEN);
-
- CLIENT_USER(query->client, user)
- who_am_i = user->name;
-
- if (children->node == NULL)
- {
- /* show all properties */
- int i;
-
- for (i = 0; i < KW_COUNT; i++)
- {
- if ((prop_cb = siridb_props[i]) == NULL)
- {
- continue;
- }
- prop_cb(siridb, query->packer, 1);
- }
- }
- else
- {
- /* show selected properties chosen by query */
- while (1)
- {
- /* get the callback */
- prop_cb = siridb_props[children->node->children->node->
- cl_obj->gid - KW_OFFSET];
-#if DEBUG
- assert (prop_cb != NULL); /* all props are implemented */
-#endif
- prop_cb(siridb, query->packer, 1);
-
- if (children->next == NULL)
- {
- break;
- }
-
- /* skip one which is the delimiter */
- children = children->next->next;
- }
- }
-
- qp_add_type(query->packer, QP_ARRAY_CLOSE);
-
- SIRIPARSER_ASYNC_NEXT_NODE
-}
-
-static void exit_timeit_stmt(uv_async_t * handle)
-{
- siridb_query_t * query = (siridb_query_t *) handle->data;
- CLIENT_SIRIDB(query->client, siridb)
-
- struct timespec end;
- char * name = siridb->server->name;
- clock_gettime(CLOCK_REALTIME, &end);
-
- qp_add_type(query->timeit, QP_MAP2);
- qp_add_raw(query->timeit, (const unsigned char *) "server", 6);
- qp_add_string(query->timeit, name);
- qp_add_raw(query->timeit, (const unsigned char *) "time", 4);
- qp_add_double(query->timeit,
- (double) (end.tv_sec - query->start.tv_sec) +
- (double) (end.tv_nsec - query->start.tv_nsec) / 1000000000.0f);
-
- if (query->packer == NULL)
- {
- /* lets give the new packer the exact size so we do not
- * need a realloc */
- query->packer = sirinet_packer_new(
- query->timeit->len +
- 1 +
- sizeof(sirinet_pkg_t));
-
- if (query->packer == NULL)
- {
- MEM_ERR_RET
- }
-
- qp_add_type(query->packer, QP_MAP_OPEN);
- }
-
- /* extend packer with timeit information */
- qp_packer_extend(query->packer, query->timeit);
-
- SIRIPARSER_ASYNC_NEXT_NODE
-}
-
-/******************************************************************************
- * Async loop functions.
- *****************************************************************************/
-
-static void async_count_series(uv_async_t * handle)
-{
- siridb_query_t * query = (siridb_query_t *) handle->data;
- siridb_series_t * series;
- query_count_t * q_count = (query_count_t *) query->data;
- uint8_t async_more = 0;
-
- size_t index_end = q_count->slist_index + MAX_ITERATE_COUNT;
-
- if (index_end >= q_count->slist->len)
- {
- index_end = q_count->slist->len;
- }
- else
- {
- async_more = 1;
- }
-
- for (; q_count->slist_index < index_end; q_count->slist_index++)
- {
- series = (siridb_series_t *) q_count->slist->data[q_count->slist_index];
- q_count->n += cexpr_run(
- q_count->where_expr,
- (cexpr_cb_t) siridb_series_cexpr_cb,
- series);
- siridb_series_decref(series);
- }
-
- if (async_more)
- {
- uv_async_send(handle);
- }
- else if (IS_MASTER)
- {
- siridb_query_forward(
- handle,
- SIRIDB_QUERY_FWD_POOLS,
- (sirinet_promises_cb) on_count_xxx_response,
- 0);
- }
- else
- {
- qp_add_int64(query->packer, q_count->n);
-
- SIRIPARSER_ASYNC_NEXT_NODE
- }
-}
-
-static void async_count_series_length(uv_async_t * handle)
-{
- siridb_query_t * query = (siridb_query_t *) handle->data;
- siridb_series_t * series;
- query_count_t * q_count = (query_count_t *) query->data;
- uint8_t async_more = 0;
-
- size_t index_end = q_count->slist_index + MAX_ITERATE_COUNT;
-
- if (index_end >= q_count->slist->len)
- {
- index_end = q_count->slist->len;
- }
- else
- {
- async_more = 1;
- }
-
- for (; q_count->slist_index < index_end; q_count->slist_index++)
- {
- series = (siridb_series_t *) q_count->slist->data[q_count->slist_index];
-
- if (cexpr_run(
- q_count->where_expr,
- (cexpr_cb_t) siridb_series_cexpr_cb,
- series))
- {
- q_count->n += series->length;
- }
-
- siridb_series_decref(series);
- }
-
- if (async_more)
- {
- uv_async_send(handle);
- }
- else if (IS_MASTER)
- {
- siridb_query_forward(
- handle,
- SIRIDB_QUERY_FWD_POOLS,
- (sirinet_promises_cb) on_count_xxx_response,
- 0);
- }
- else
- {
- qp_add_int64(query->packer, q_count->n);
-
- SIRIPARSER_ASYNC_NEXT_NODE
- }
-}
-
-static void async_drop_series(uv_async_t * handle)
-{
- siridb_query_t * query = (siridb_query_t *) handle->data;
- query_drop_t * q_drop = (query_drop_t *) query->data;
- CLIENT_SIRIDB(query->client, siridb)
-
- siridb_series_t * series;
- uint8_t async_more = 0;
-
- size_t index_end = q_drop->slist_index + MAX_ITERATE_COUNT;
-
- if (index_end >= q_drop->slist->len)
- {
- index_end = q_drop->slist->len;
- }
- else
- {
- async_more = 1;
- }
-
- uv_mutex_lock(&siridb->series_mutex);
-
- for (; q_drop->slist_index < index_end; q_drop->slist_index++)
- {
- series = (siridb_series_t *) q_drop->slist->data[q_drop->slist_index];
- siridb_series_drop(siridb, series);
- siridb_series_decref(series);
- }
-
- uv_mutex_unlock(&siridb->series_mutex);
-
- /* flush dropped file change to disk */
- if (q_drop->slist->len)
- {
- siridb_series_flush_dropped(siridb);
- }
-
- if (async_more)
- {
- uv_async_send(handle);
- }
- else if (IS_MASTER)
- {
- siridb_query_forward(
- handle,
- SIRIDB_QUERY_FWD_UPDATE,
- (sirinet_promises_cb) on_drop_series_response,
- 0);
- }
- else
- {
- qp_add_int64(query->packer, q_drop->n);
-
- SIRIPARSER_ASYNC_NEXT_NODE
- }
-}
-
-static void async_drop_shards(uv_async_t * handle)
-{
- siridb_query_t * query = (siridb_query_t *) handle->data;
- query_drop_t * q_drop = (query_drop_t *) query->data;
- CLIENT_SIRIDB(query->client, siridb)
-
- if (q_drop->shards_list->len)
- {
- siridb_shard_t * shard = (siridb_shard_t *) slist_pop(
- q_drop->shards_list);
-
- siridb_shard_drop(
- shard,
- siridb);
- siridb_shard_decref(shard);
- }
-
- if (q_drop->shards_list->len)
- {
- uv_async_send(handle);
- }
- else if (IS_MASTER)
- {
- siridb_query_forward(
- handle,
- SIRIDB_QUERY_FWD_UPDATE,
- (sirinet_promises_cb) on_drop_shards_response,
- 0);
- }
- else
- {
- qp_add_int64(query->packer, q_drop->n);
- SIRIPARSER_ASYNC_NEXT_NODE
- }
-}
-
-static void async_filter_series(uv_async_t * handle)
-{
- siridb_query_t * query = (siridb_query_t *) handle->data;
- query_wrapper_t * q_wrapper = (query_wrapper_t *) query->data;
- cexpr_t * where_expr = q_wrapper->where_expr;
- uint8_t async_more = 0;
- siridb_series_t * series;
- size_t index_end = q_wrapper->slist_index + MAX_ITERATE_COUNT;
-
- if (index_end >= q_wrapper->slist->len)
- {
- index_end = q_wrapper->slist->len;
- }
- else
- {
- async_more = 1;
- }
-
- for (; q_wrapper->slist_index < index_end; q_wrapper->slist_index++)
- {
- series = (siridb_series_t *)
- q_wrapper->slist->data[q_wrapper->slist_index];
-
- if (cexpr_run(
- where_expr,
- (cexpr_cb_t) siridb_series_cexpr_cb,
- series))
- {
- if (imap_add(q_wrapper->series_map, series->id, series))
- {
- log_critical("Cannot add filtered series to internal map.");
- siridb_series_decref(series);
- }
- }
- else
- {
- siridb_series_decref(series);
- }
- }
-
- if (async_more)
- {
- uv_async_send(handle);
- }
- else
- {
- /* free the s-list object and reset index */
- slist_free(q_wrapper->slist);
-
- q_wrapper->slist = NULL;
- q_wrapper->slist_index = 0;
-
- /* cleanup where statement since we do not need it anymore */
- cexpr_free(q_wrapper->where_expr);
- q_wrapper->where_expr = NULL;
-
- /* we now processed the where statement, continue... */
- switch (q_wrapper->tp)
- {
- case QUERIES_DROP:
- exit_drop_series(handle);
- break;
- case QUERIES_SELECT:
- exit_select_aggregate(handle);
- break;
- default:
- assert (0);
- break;
- }
- }
-}
-
-static void async_list_series(uv_async_t * handle)
-{
- siridb_query_t * query = (siridb_query_t *) handle->data;
- query_list_t * q_list = (query_list_t *) query->data;
- slist_t * props = q_list->props;
- cexpr_t * where_expr = q_list->where_expr;
- uint8_t async_more = 0;
- siridb_series_t * series;
- size_t i;
- size_t index_end = q_list->slist_index + MAX_ITERATE_COUNT;
-
- if (index_end >= q_list->slist->len)
- {
- index_end = q_list->slist->len;
- }
- else
- {
- async_more = 1;
- }
-
- for (; q_list->limit && q_list->slist_index < index_end;
- q_list->slist_index++)
- {
- series = (siridb_series_t *) q_list->slist->data[q_list->slist_index];
-
- if (where_expr == NULL || cexpr_run(
- where_expr,
- (cexpr_cb_t) siridb_series_cexpr_cb,
- series))
- {
- if (!--q_list->limit)
- {
- async_more = 0;
- }
-
- qp_add_type(query->packer, QP_ARRAY_OPEN);
-
- for (i = 0; i < props->len; i++)
- {
- switch(*((uint32_t *) props->data[i]))
- {
- case CLERI_GID_K_NAME:
- qp_add_raw(
- query->packer,
- (const unsigned char *) series->name,
- series->name_len);
- break;
- case CLERI_GID_K_LENGTH:
- qp_add_int32(query->packer, series->length);
- break;
- case CLERI_GID_K_TYPE:
- qp_add_string(query->packer, series_type_map[series->tp]);
- break;
- case CLERI_GID_K_POOL:
- qp_add_int16(query->packer, series->pool);
- break;
- case CLERI_GID_K_START:
- qp_add_int64(query->packer, series->start);
- break;
- case CLERI_GID_K_END:
- qp_add_int64(query->packer, series->end);
- break;
- }
- }
-
- qp_add_type(query->packer, QP_ARRAY_CLOSE);
- }
-
- siridb_series_decref(series);
- }
-
- if (async_more)
- {
- uv_async_send(handle);
- }
- else if (IS_MASTER && q_list->limit)
- {
- /* we have not reached the limit, send the query to other pools */
- siridb_query_forward(
- handle,
- SIRIDB_QUERY_FWD_POOLS,
- (sirinet_promises_cb) on_list_xxx_response,
- 0);
- }
- else
- {
- qp_add_type(query->packer, QP_ARRAY_CLOSE);
-
- SIRIPARSER_ASYNC_NEXT_NODE
- }
-}
-
-static void async_no_points_aggregate(uv_async_t * handle)
-{
- siridb_query_t * query = (siridb_query_t *) handle->data;
- query_select_t * q_select = (query_select_t *) query->data;
- CLIENT_SIRIDB(query->client, siridb)
- uint8_t async_more = 0;
- siridb_series_t * series;
- siridb_points_t * points;
- siridb_points_t * aggr_points;
- int required_shard = 0;
-
- for (; q_select->slist_index < q_select->slist->len;
- ++q_select->slist_index)
- {
- if (required_shard > MAX_BATCH_REQUIRE_SHARD)
- {
- async_more = 1;
- break;
- }
-
- series = (siridb_series_t *)
- q_select->slist->data[q_select->slist_index];
- /*
- * We must decrement the ref count immediately since the index is
- * incremented by one. The series will not be freed since at least
- * 'series_map' still has a reference.
- */
- siridb_series_decref(series);
-
-#if DEBUG
- assert (q_select->alist->len >= 1);
-#endif
-
- siridb_aggr_t * aggr = q_select->alist->data[0];
-
- uv_mutex_lock(&siridb->series_mutex);
-
- switch (aggr->gid)
- {
- case CLERI_GID_F_COUNT:
- points = siridb_series_get_count(series);
- break;
- case CLERI_GID_F_FIRST:
- points = siridb_series_get_first(series, &required_shard);
- break;
- case CLERI_GID_F_LAST:
- points = siridb_series_get_last(series, &required_shard);
- break;
- default:
- assert (0);
- }
-
- uv_mutex_unlock(&siridb->series_mutex);
-
- if (points != NULL)
- {
- const char * name;
- size_t i;
-
- for (i = 1; points->len && i < q_select->alist->len; i++)
- {
- aggr_points = siridb_aggregate_run(
- points,
- (siridb_aggr_t *) q_select->alist->data[i],
- query->err_msg);
-
- if (aggr_points != points)
- {
- siridb_points_free(points);
- }
-
- if (aggr_points == NULL)
- {
- siridb_query_send_error(handle, CPROTO_ERR_QUERY);
- return;
- }
-
- points = aggr_points;
- }
-
- q_select->n += points->len;
-
- if (q_select->merge_as == NULL)
- {
- name = siridb_presuf_name(
- q_select->presuf,
- series->name,
- series->name_len);
-
- if (name == NULL || ct_add(q_select->result, name, points))
- {
- sprintf(query->err_msg, "Error adding points to map.");
- siridb_points_free(points);
- log_critical("Critical error adding points");
- siridb_query_send_error(handle, CPROTO_ERR_QUERY);
- return;
- }
- }
- else
- {
- slist_t ** plist;
-
- name = siridb_presuf_name(
- q_select->presuf,
- q_select->merge_as,
- strlen(q_select->merge_as));
-
- plist = (slist_t **) ct_getaddr(q_select->result, name);
-
- if ( name == NULL ||
- plist == NULL ||
- slist_append_safe(plist, points))
- {
- sprintf(query->err_msg, "Error adding points to map.");
- siridb_points_free(points);
- log_critical("Critical error adding points");
- siridb_query_send_error(handle, CPROTO_ERR_QUERY);
- return;
- }
- }
- }
- }
-
- if (async_more)
- {
- uv_async_send(handle);
- }
- else
- {
- siridb_aggregate_list_free(q_select->alist);
- q_select->alist = NULL;
-
- slist_free(q_select->slist);
- q_select->slist = NULL;
- q_select->slist_index = 0;
-
- SIRIPARSER_ASYNC_NEXT_NODE
- }
-}
-
-static void async_select_aggregate(uv_async_t * handle)
-{
- siridb_query_t * query = (siridb_query_t *) handle->data;
- query_select_t * q_select = (query_select_t *) query->data;
- CLIENT_SIRIDB(query->client, siridb)
- uint8_t async_more = 0;
- siridb_series_t * series;
- siridb_points_t * points;
- siridb_points_t * aggr_points;
-
- if (q_select->n > siridb->select_points_limit)
- {
- snprintf(query->err_msg,
- SIRIDB_MAX_SIZE_ERR_MSG,
- "Query has reached the maximum number of selected points "
- "(%u). Please use another time window, an aggregation "
- "function or select less series to reduce the number of "
- "points.",
- siridb->select_points_limit);
-
- siridb_query_send_error(handle, CPROTO_ERR_QUERY);
- return;
- }
-
- series = (siridb_series_t *)
- q_select->slist->data[q_select->slist_index];
-
- /*
- * We must decrement the ref count immediately since we now update the
- * index by one. The series will not be freed since at least 'series_map'
- * still has a reference.
- */
- siridb_series_decref(series);
-
- if ((++q_select->slist_index) < q_select->slist->len)
- {
- async_more = 1;
- }
-
- /* We try to read the points from the cache in case a cache is created.
- * If there are more select functions left we create a copy of the cache.
- * When this is the last select function we pop from the cache since the
- * points are no longer required.
- */
- points = (q_select->points_map == NULL) ?
- NULL :
- q_select->nselects ?
- siridb_points_copy(imap_get(q_select->points_map, series->id)):
- imap_pop(q_select->points_map, series->id);
-
- if (points == NULL)
- {
- uv_mutex_lock(&siridb->series_mutex);
-
- points = (series->flags & SIRIDB_SERIES_IS_DROPPED) ?
- NULL : siridb_series_get_points(
- series,
- q_select->start_ts,
- q_select->end_ts);
- uv_mutex_unlock(&siridb->series_mutex);
-
- /* when having a cache and points, add a copy of points to the cache */
- if (q_select->points_map != NULL && points != NULL)
- {
- siridb_points_t * cpoints = siridb_points_copy(points);
- if (cpoints != NULL &&
- imap_add(q_select->points_map, series->id, cpoints))
- {
- siridb_points_free(cpoints);
- }
- }
- }
-
- if (points != NULL)
- {
- const char * name;
- size_t i;
-
- for (i = 0; points->len && i < q_select->alist->len; i++)
- {
- aggr_points = siridb_aggregate_run(
- points,
- (siridb_aggr_t *) q_select->alist->data[i],
- query->err_msg);
-
- if (aggr_points != points)
- {
- siridb_points_free(points);
- }
-
- if (aggr_points == NULL)
- {
- siridb_query_send_error(handle, CPROTO_ERR_QUERY);
- return;
- }
-
- points = aggr_points;
- }
-
- q_select->n += points->len;
-
- if (q_select->merge_as == NULL)
- {
- name = siridb_presuf_name(
- q_select->presuf,
- series->name,
- series->name_len);
-
- if (name == NULL || ct_add(q_select->result, name, points))
- {
- sprintf(query->err_msg, "Error adding points to map.");
- siridb_points_free(points);
- log_critical("Critical error adding points");
- siridb_query_send_error(handle, CPROTO_ERR_QUERY);
- return;
- }
- }
- else
- {
- slist_t ** plist;
-
- name = siridb_presuf_name(
- q_select->presuf,
- q_select->merge_as,
- strlen(q_select->merge_as));
-
- plist = (slist_t **) ct_getaddr(q_select->result, name);
-
- if ( name == NULL ||
- plist == NULL ||
- slist_append_safe(plist, points))
- {
- sprintf(query->err_msg, "Error adding points to map.");
- siridb_points_free(points);
- log_critical("Critical error adding points");
- siridb_query_send_error(handle, CPROTO_ERR_QUERY);
- return;
- }
- }
- }
-
- if (async_more)
- {
- uv_async_send(handle);
- }
- else
- {
- siridb_aggregate_list_free(q_select->alist);
- q_select->alist = NULL;
-
- slist_free(q_select->slist);
- q_select->slist = NULL;
- q_select->slist_index = 0;
-
- SIRIPARSER_ASYNC_NEXT_NODE
- }
-}
-
-static void async_series_re(uv_async_t * handle)
-{
- siridb_query_t * query = (siridb_query_t *) handle->data;
- query_wrapper_t * q_wrapper = (query_wrapper_t *) query->data;
- uint8_t async_more = 0;
- siridb_series_t * series;
- size_t index_end = q_wrapper->slist_index + MAX_ITERATE_COUNT;
-
- if (index_end >= q_wrapper->slist->len)
- {
- index_end = q_wrapper->slist->len;
- }
- else
- {
- async_more = 1;
- }
-
- int pcre_exec_ret;
-
- for (; q_wrapper->slist_index < index_end; q_wrapper->slist_index++)
- {
- series = (siridb_series_t *)
- q_wrapper->slist->data[q_wrapper->slist_index];
-
- pcre_exec_ret = pcre2_match(
- q_wrapper->regex,
- (PCRE2_SPTR8) series->name,
- series->name_len,
- 0, /* start looking at this point */
- 0, /* OPTIONS */
- q_wrapper->match_data,
- 0); /* length of sub_str_vec */
- if ( pcre_exec_ret < 0 ||
- imap_add(q_wrapper->series_tmp, series->id, series))
- {
- siridb_series_decref(series);
- }
- }
-
- if (async_more)
- {
- uv_async_send(handle);
- }
- else
- {
- /* free the s-list object and reset index */
- slist_free(q_wrapper->slist);
-
- pcre2_code_free(q_wrapper->regex);
- pcre2_match_data_free(q_wrapper->match_data);
-
- q_wrapper->regex = NULL;
- q_wrapper->match_data = NULL;
-
- q_wrapper->slist = NULL;
- q_wrapper->slist_index = 0;
-
- if (q_wrapper->update_cb != NULL)
- {
- (*q_wrapper->update_cb)(
- q_wrapper->series_map,
- q_wrapper->series_tmp,
- (imap_free_cb) &siridb__series_decref);
- }
- q_wrapper->series_tmp = NULL;
-
- SIRIPARSER_ASYNC_NEXT_NODE
- }
-}
-
-/******************************************************************************
- * On Response functions
- *****************************************************************************/
-
-/*
- * Call-back function: sirinet_promise_cb
- */
-static void on_ack_response(
- sirinet_promise_t * promise,
- sirinet_pkg_t * pkg,
- int status)
-{
- uv_async_t * handle = (uv_async_t *) promise->data;
-
- /* decrement the handle reference counter */
- siri_async_decref(&handle);
-
- if (handle != NULL)
- {
- siridb_query_t * query = (siridb_query_t *) handle->data;
-
- if (status == PROMISE_SUCCESS)
- {
- switch (pkg->tp)
- {
- case BPROTO_ACK_LOG_LEVEL:
- /* success message is already set */
- break;
- case BPROTO_ACK_ENABLE_BACKUP_MODE:
- /* success message is already set */
- break;
- case BPROTO_ACK_DISABLE_BACKUP_MODE:
- /* success message is already set */
- break;
-
- default:
- status = PROMISE_PKG_TYPE_ERROR;
- break;
- }
- }
-
- if (status)
- {
- snprintf(query->err_msg,
- SIRIDB_MAX_SIZE_ERR_MSG,
- "Error occurred while sending the request to '%s' (%s)",
- promise->server->name,
- sirinet_promise_strstatus(status));
- siridb_query_send_error(handle, CPROTO_ERR_QUERY);
- }
- else
- {
- SIRIPARSER_ASYNC_NEXT_NODE
- }
- }
-
- /* we must free the promise */
- sirinet_promise_decref(promise);
-}
-
-/*
- * Call-back function: sirinet_promises_cb
- *
- * Make sure to run siri_async_incref() on the handle
- */
-static void on_alter_xxx_response(slist_t * promises, uv_async_t * handle)
-{
- ON_PROMISES
-
- siridb_query_t * query = (siridb_query_t *) handle->data;
- sirinet_pkg_t * pkg;
- sirinet_promise_t * promise;
- qp_unpacker_t unpacker;
- qp_obj_t qp_count;
- query_alter_t * q_alter = (query_alter_t *) query->data;
- size_t i;
-
- for (i = 0; i < promises->len; i++)
- {
- promise = promises->data[i];
-
- if (promise == NULL)
- {
- continue;
- }
-
- pkg = (sirinet_pkg_t *) promise->data;
-
- if (pkg != NULL && pkg->tp == BPROTO_RES_QUERY)
- {
- qp_unpacker_init(&unpacker, pkg->data, pkg->len);
-
- if ( qp_is_map(qp_next(&unpacker, NULL)) &&
- qp_is_raw(qp_next(&unpacker, NULL)) && /* servers etc.*/
- qp_is_int(qp_next(&unpacker, &qp_count))) /* one result*/
- {
- q_alter->n += qp_count.via.int64;
-
- /* extract time-it info if needed */
- if (query->timeit != NULL)
- {
- siridb_query_timeit_from_unpacker(query, &unpacker);
- }
- }
- }
-
- /* make sure we free the promise and data */
- free(promise->data);
- sirinet_promise_decref(promise);
- }
- /*
- * Note: since this function has the sole purpose for alter servers
- * and setting log levels, we now simply ad the message here.
- */
- QP_ADD_SUCCESS
-
- log_info(MSG_SUCCES_SET_LOG_LEVEL_MULTI,
- logger_level_name(q_alter->n >> 16),
- q_alter->n & 0xffff);
-
- qp_add_fmt_safe(
- query->packer,
- MSG_SUCCES_SET_LOG_LEVEL_MULTI,
- logger_level_name(q_alter->n >> 16),
- q_alter->n & 0xffff);
-
- SIRIPARSER_ASYNC_NEXT_NODE
-}
-
-/*
- * Call-back function: sirinet_promises_cb
- *
- * Make sure to run siri_async_incref() on the handle
- */
-static void on_count_xxx_response(slist_t * promises, uv_async_t * handle)
-{
- ON_PROMISES
-
- uint8_t error_tp = 0;
- siridb_query_t * query = (siridb_query_t *) handle->data;
- sirinet_pkg_t * pkg;
- sirinet_promise_t * promise;
- qp_unpacker_t unpacker;
- qp_obj_t qp_count;
- query_count_t * q_count = (query_count_t *) query->data;
- size_t i;
-
- for (i = 0; i < promises->len; i++)
- {
- promise = promises->data[i];
-
- if (promise == NULL)
- {
- continue;
- }
-
- pkg = (sirinet_pkg_t *) promise->data;
-
- if (pkg != NULL && pkg->tp == BPROTO_RES_QUERY)
- {
- qp_unpacker_init(&unpacker, pkg->data, pkg->len);
-
- if ( qp_is_map(qp_next(&unpacker, NULL)) &&
- qp_is_raw(qp_next(&unpacker, NULL)) && /* servers etc.*/
- qp_is_int(qp_next(&unpacker, &qp_count))) /* one result*/
- {
- q_count->n += qp_count.via.int64;
-
- /* extract time-it info if needed */
- if (query->timeit != NULL)
- {
- siridb_query_timeit_from_unpacker(query, &unpacker);
- }
- }
- }
- else if (pkg != NULL &&
- !error_tp &&
- sirinet_protocol_is_error_msg(pkg->tp) &&
- siridb_query_err_from_pkg(query, pkg) == 0)
- {
- error_tp = pkg->tp;
- }
-
- /* make sure we free the promise and data */
- free(promise->data);
- sirinet_promise_decref(promise);
- }
-
- if (error_tp)
- {
- siridb_query_send_error(handle, error_tp);
- }
- else
- {
- qp_add_int64(query->packer, q_count->n);
-
- SIRIPARSER_ASYNC_NEXT_NODE
- }
-}
-
-/*
- * Call-back function: sirinet_promises_cb
- *
- * Make sure to run siri_async_incref() on the handle
- */
-static void on_drop_series_response(slist_t * promises, uv_async_t * handle)
-{
- ON_PROMISES
-
- siridb_query_t * query = (siridb_query_t *) handle->data;
- sirinet_pkg_t * pkg;
- sirinet_promise_t * promise;
- qp_unpacker_t unpacker;
- qp_obj_t qp_drop;
- query_drop_t * q_drop = (query_drop_t *) query->data;
- size_t i;
-
- for (i = 0; i < promises->len; i++)
- {
- promise = promises->data[i];
-
- if (promise == NULL)
- {
- continue;
- }
-
- pkg = (sirinet_pkg_t *) promise->data;
-
- if (pkg != NULL && pkg->tp == BPROTO_RES_QUERY)
- {
- qp_unpacker_init(&unpacker, pkg->data, pkg->len);
-
- if ( qp_is_map(qp_next(&unpacker, NULL)) &&
- qp_is_raw(qp_next(&unpacker, NULL)) && /* servers etc.*/
- qp_is_int(qp_next(&unpacker, &qp_drop))) /* one result */
- {
- q_drop->n += qp_drop.via.int64;
-
- /* extract time-it info if needed */
- if (query->timeit != NULL)
- {
- siridb_query_timeit_from_unpacker(query, &unpacker);
- }
- }
- }
-
- /* make sure we free the promise and data */
- free(promise->data);
- sirinet_promise_decref(promise);
- }
-
- qp_add_fmt(query->packer, MSG_SUCCES_DROP_SERIES, q_drop->n);
-
- SIRIPARSER_ASYNC_NEXT_NODE
-}
-
-/*
- * Call-back function: sirinet_promises_cb
- *
- * Make sure to run siri_async_incref() on the handle
- */
-static void on_drop_shards_response(slist_t * promises, uv_async_t * handle)
-{
- ON_PROMISES
-
- siridb_query_t * query = (siridb_query_t *) handle->data;
- sirinet_pkg_t * pkg;
- sirinet_promise_t * promise;
- qp_unpacker_t unpacker;
- qp_obj_t qp_drop;
- query_drop_t * q_drop = (query_drop_t *) query->data;
- size_t i;
-
- for (i = 0; i < promises->len; i++)
- {
- promise = promises->data[i];
-
- if (promise == NULL)
- {
- continue;
- }
-
- pkg = (sirinet_pkg_t *) promise->data;
-
- if (pkg != NULL && pkg->tp == BPROTO_RES_QUERY)
- {
- qp_unpacker_init(&unpacker, pkg->data, pkg->len);
-
- if ( qp_is_map(qp_next(&unpacker, NULL)) &&
- qp_is_raw(qp_next(&unpacker, NULL)) && /* shards */
- qp_is_int(qp_next(&unpacker, &qp_drop))) /* one result */
- {
- q_drop->n += qp_drop.via.int64;
-
- /* extract time-it info if needed */
- if (query->timeit != NULL)
- {
- siridb_query_timeit_from_unpacker(query, &unpacker);
- }
- }
- }
-
- /* make sure we free the promise and data */
- free(promise->data);
- sirinet_promise_decref(promise);
- }
-
- qp_add_fmt(query->packer, MSG_SUCCES_DROP_SHARDS, q_drop->n);
-
- SIRIPARSER_ASYNC_NEXT_NODE
-}
-
-/*
- * Call-back function: sirinet_promises_cb
- *
- * Make sure to run siri_async_incref() on the handle
- */
-static void on_groups_response(slist_t * promises, uv_async_t * handle)
-{
- ON_PROMISES
-
- sirinet_pkg_t * pkg;
- sirinet_promise_t * promise;
- qp_unpacker_t unpacker;
- siridb_query_t * query = (siridb_query_t *) handle->data;
- CLIENT_SIRIDB(query->client, siridb)
- siridb_group_t * group;
- qp_obj_t qp_name;
- qp_obj_t qp_series;
- size_t i;
-
- siridb_groups_init_nseries(siridb->groups);
-
- for (i = 0; i < promises->len; i++)
- {
- promise = promises->data[i];
-
- if (promise == NULL)
- {
- continue;
- }
-
- pkg = (sirinet_pkg_t *) promise->data;
-
- if (pkg != NULL && pkg->tp == BPROTO_RES_GROUPS)
- {
- qp_unpacker_init(&unpacker, pkg->data, pkg->len);
-
- if ( qp_is_array(qp_next(&unpacker, NULL)))
- {
- while ( qp_is_array(qp_next(&unpacker, NULL)) &&
- qp_is_raw(qp_next(&unpacker, &qp_name)) &&
- qp_is_raw_term(&qp_name) &&
- qp_is_int(qp_next(&unpacker, &qp_series)))
- {
- group = (siridb_group_t *) ct_get(
- siridb->groups->groups,
- (const char *) qp_name.via.raw);
- if (group != NULL)
- {
- group->n += qp_series.via.int64;
- }
- }
- }
- }
-
- /* make sure we free the promise and data */
- free(promise->data);
- sirinet_promise_decref(promise);
- }
-
- query->nodes->cb(handle);
-}
-
-/*
- * Call-back function: sirinet_promises_cb
- *
- * Make sure to run siri_async_incref() on the handle
- */
-static void on_list_xxx_response(slist_t * promises, uv_async_t * handle)
-{
- ON_PROMISES
-
- int error_tp = 0;
- sirinet_pkg_t * pkg;
- sirinet_promise_t * promise;
- qp_unpacker_t unpacker;
- siridb_query_t * query = (siridb_query_t *) handle->data;
- query_list_t * q_list = (query_list_t *) query->data;
- size_t i;
-
- for (i = 0; i < promises->len; i++)
- {
- promise = promises->data[i];
-
- if (promise == NULL)
- {
- continue;
- }
-
- pkg = (sirinet_pkg_t *) promise->data;
-
- if (pkg != NULL && pkg->tp == BPROTO_RES_QUERY)
- {
- qp_unpacker_init(&unpacker, pkg->data, pkg->len);
-
- if ( qp_is_map(qp_next(&unpacker, NULL)) &&
- qp_is_raw(qp_next(&unpacker, NULL)) && /* columns */
- qp_is_array(qp_skip_next(&unpacker)) &&
- qp_is_raw(qp_next(&unpacker, NULL)) && /* series/... */
- qp_is_array(qp_next(&unpacker, NULL))) /* results */
- {
- while (qp_is_array(qp_current(&unpacker)))
- {
- if (q_list->limit)
- {
- qp_packer_extend_fu(query->packer, &unpacker);
- q_list->limit--;
- }
- else
- {
- qp_skip_next(&unpacker);
- }
- }
-
- /* extract time-it info if needed */
- if (query->timeit != NULL)
- {
- siridb_query_timeit_from_unpacker(query, &unpacker);
- }
- }
- }
- else if (pkg != NULL &&
- !error_tp &&
- sirinet_protocol_is_error_msg(pkg->tp) &&
- siridb_query_err_from_pkg(query, pkg) == 0)
- {
- error_tp = pkg->tp;
- }
-
- /* make sure we free the promise and data */
- free(promise->data);
- sirinet_promise_decref(promise);
- }
-
- if (error_tp)
- {
- siridb_query_send_error(handle, error_tp);
- }
- else
- {
- qp_add_type(query->packer, QP_ARRAY_CLOSE);
- SIRIPARSER_ASYNC_NEXT_NODE
- }
-}
-
-/*
- * Call-back function: sirinet_promises_cb
- *
- * Make sure to run siri_async_incref() on the handle
- */
-static void on_select_response(slist_t * promises, uv_async_t * handle)
-{
- ON_PROMISES
-
- sirinet_pkg_t * pkg;
- sirinet_promise_t * promise;
- qp_unpacker_t unpacker;
- siridb_query_t * query = (siridb_query_t *) handle->data;
- CLIENT_SIRIDB(query->client, siridb)
- size_t err_count = 0;
- query_select_t * q_select = (query_select_t *) query->data;
- qp_obj_t qp_name;
- qp_obj_t qp_tp;
- qp_obj_t qp_len;
- qp_obj_t qp_points;
- qp_obj_t qp_err_msg;
- size_t i;
-
- for (i = 0; i < promises->len; i++)
- {
- promise = promises->data[i];
-
- if (promise == NULL)
- {
- err_count++;
- snprintf(query->err_msg,
- SIRIDB_MAX_SIZE_ERR_MSG,
- "Error occurred while sending the select query to at "
- "least one required server");
- }
- else
- {
- pkg = (sirinet_pkg_t *) promise->data;
-
- if (pkg == NULL || pkg->tp != BPROTO_RES_QUERY)
- {
- err_count++;
-
- if (pkg != NULL && pkg->tp == BPROTO_ERR_QUERY)
- {
- qp_unpacker_init(&unpacker, pkg->data, pkg->len);
-
- if ( qp_is_map(qp_next(&unpacker, NULL)) &&
- qp_is_raw(qp_next(&unpacker, NULL)) &&
- qp_is_raw(qp_next(&unpacker, &qp_err_msg)))
- {
- snprintf(query->err_msg,
- SIRIDB_MAX_SIZE_ERR_MSG,
- "%.*s",
- (int) qp_err_msg.len,
- qp_err_msg.via.raw);
- }
- else
- {
- snprintf(query->err_msg,
- SIRIDB_MAX_SIZE_ERR_MSG,
- "Error occurred while sending request to "
- "at least '%s'",
- promise->server->name);
- }
- }
- else
- {
- snprintf(query->err_msg,
- SIRIDB_MAX_SIZE_ERR_MSG,
- "Error occurred while sending request to "
- "at least '%s'",
- promise->server->name);
- }
- }
- else
- {
- qp_unpacker_init(&unpacker, pkg->data, pkg->len);
-
- if ( qp_is_map(qp_next(&unpacker, NULL)) &&
- qp_is_raw(qp_next(&unpacker, NULL)) && /* select */
- qp_is_map(qp_next(&unpacker, NULL)))
- {
- if (q_select->merge_as == NULL)
- {
- on_select_unpack_points(
- &unpacker,
- q_select,
- &qp_name,
- &qp_tp,
- &qp_len,
- &qp_points,
- siridb->select_points_limit);
- }
- else
- {
- on_select_unpack_merged_points(
- &unpacker,
- q_select,
- &qp_name,
- &qp_tp,
- &qp_len,
- &qp_points,
- siridb->select_points_limit);
- }
-
-
- /* extract time-it info if needed */
- if (query->timeit != NULL)
- {
- siridb_query_timeit_from_unpacker(query, &unpacker);
- }
- }
- }
-
- /* make sure we free the promise and data */
- free(promise->data);
- sirinet_promise_decref(promise);
- }
- }
-
- if (q_select->n > siridb->select_points_limit)
- {
- snprintf(query->err_msg,
- SIRIDB_MAX_SIZE_ERR_MSG,
- "Query has reached the maximum number of selected points "
- "(%u). Please use another time window, an aggregation "
- "function or select less series to reduce the number of "
- "points.",
- siridb->select_points_limit);
- siridb_query_send_error(handle, CPROTO_ERR_QUERY);
- }
- else if (err_count)
- {
- siridb_query_send_error(handle, CPROTO_ERR_QUERY);
- }
- else
- {
- uv_async_t * next;
- uv_work_t * work = (uv_work_t *) malloc(sizeof(uv_work_t));
- if (work == NULL)
- {
- MEM_ERR_RET
- }
-
- next = (uv_async_t *) malloc(sizeof(uv_async_t));
- if (next == NULL)
- {
- free(work);
- MEM_ERR_RET
- }
-
- uv_close((uv_handle_t *) handle, (uv_close_cb) free);
-
- handle = next;
- handle->data = query;
- siridb_nodes_next(&query->nodes);
-
- uv_async_init(
- siri.loop,
- handle,
- (query->nodes == NULL) ?
- (uv_async_cb) siridb_send_query_result :
- (uv_async_cb) query->nodes->cb);
-
- siri_async_incref(handle);
- work->data = handle;
- uv_queue_work(
- siri.loop,
- work,
- &master_select_work,
- &master_select_work_finish);
-
- }
-}
-
-/*
- * Call-back function: sirinet_promises_cb
- *
- * Make sure to run siri_async_incref() on the handle
- */
-static void on_update_xxx_response(slist_t * promises, uv_async_t * handle)
-{
- ON_PROMISES
-
- sirinet_pkg_t * pkg;
- sirinet_promise_t * promise;
- siridb_query_t * query = (siridb_query_t *) handle->data;
- size_t err_count = 0;
- size_t i;
-
- for (i = 0; i < promises->len; i++)
- {
- promise = promises->data[i];
-
- if (promise == NULL)
- {
- err_count++;
- snprintf(query->err_msg,
- SIRIDB_MAX_SIZE_ERR_MSG,
- "Error occurred while sending the database change to at "
- "least one required server");
- }
- else
- {
- pkg = (sirinet_pkg_t *) promise->data;
-
- if (pkg == NULL || pkg->tp != BPROTO_RES_QUERY)
- {
- err_count++;
- snprintf(query->err_msg,
- SIRIDB_MAX_SIZE_ERR_MSG,
- "Error occurred while sending the database change to "
- "at least '%s'", promise->server->name);
- }
-
- /* make sure we free the promise and data */
- free(promise->data);
- sirinet_promise_decref(promise);
- }
- }
-
- if (err_count)
- {
- siridb_query_send_error(handle, CPROTO_ERR_QUERY);
- }
- else
- {
- SIRIPARSER_ASYNC_NEXT_NODE
- }
-}
-
-/******************************************************************************
- * Helper functions
- *****************************************************************************/
-
-
-static void master_select_work(uv_work_t * work)
-{
- uv_async_t * handle = (uv_async_t *) work->data;
- siridb_query_t * query = (siridb_query_t *) handle->data;
- query_select_t * q_select = (query_select_t *) query->data;
- CLIENT_SIRIDB(query->client, siridb)
- siridb->selected_points += q_select->n;
- int rc = ct_items(
- q_select->result,
- (q_select->merge_as == NULL) ?
- (ct_item_cb) &items_select_master
- :
- (ct_item_cb) &items_select_master_merge,
- handle);
-
- /* Do not set an error message when rc==1 since in that case the message
- * is already set.
- */
- switch (rc)
- {
- case -1:
- sprintf(query->err_msg, "Memory allocation error.");
- /* FALLTHRU */
- /* no break */
- case 1:
- query->flags |= SIRIDB_QUERY_FLAG_ERR;
- }
-}
-
-static void master_select_work_finish(uv_work_t * work, int status)
-{
- if (status)
- {
- log_error("Select work failed (error: %s)", uv_strerror(status));
- }
- else if (!siri_err)
- {
- /*
- * We need to check for SiriDB errors because this task is running in
- * another thread. In case a siri_err is set, this means we are in forced
- * closing state and we should not use the handle but let siri close it.
- */
-
- uv_async_t * handle = (uv_async_t *) work->data;
- siridb_query_t * query = (siridb_query_t *) handle->data;
-
- if (query->flags & SIRIDB_QUERY_FLAG_ERR)
- {
- siridb_query_send_error(handle, CPROTO_ERR_QUERY);
- }
- else
- {
- uv_async_send(handle);
- }
- }
-
- siri_async_decref((uv_async_t **) &work->data);
-
- free(work);
-}
-
-static int items_select_master(
- const char * name,
- size_t len,
- siridb_points_t * points,
- uv_async_t * handle)
-{
- siridb_query_t * query = (siridb_query_t *) handle->data;
-
- if (query->factor)
- {
- siridb_points_ts_correction(points, (double) query->factor);
- }
-
- if ( qp_add_raw(query->packer, (const unsigned char *) name, len) ||
- siridb_points_pack(points, query->packer))
- {
- sprintf(query->err_msg, "Memory allocation error.");
- return -1;
- }
-
- return 0;
-}
-
-static int items_select_master_merge(
- const char * name,
- size_t len,
- slist_t * plist,
- uv_async_t * handle)
-{
- siridb_query_t * query = (siridb_query_t *) handle->data;
- query_select_t * q_select = (query_select_t *) query->data;
- siridb_points_t * points;
-
- if (qp_add_raw(query->packer, (const unsigned char *) name, len))
- {
- sprintf(query->err_msg, "Memory allocation error.");
- return -1;
- }
-
- switch (plist->len)
- {
- case 0:
- points = siridb_points_new(0, TP_INT);
- if (points == NULL)
- {
- sprintf(query->err_msg, "Memory allocation error.");
- }
- break;
- case 1:
- points = slist_pop(plist);
- break;
- default:
- points = siridb_points_merge(plist, query->err_msg);
- break;
- }
-
- if (q_select->mlist != NULL && points != NULL)
- {
- siridb_points_t * aggr_points;
- size_t i;
-
- for (i = 0; points->len && i < q_select->mlist->len; i++)
- {
- aggr_points = siridb_aggregate_run(
- points,
- (siridb_aggr_t *) q_select->mlist->data[i],
- query->err_msg);
-
- if (aggr_points != points)
- {
- siridb_points_free(points);
- }
-
- if (aggr_points == NULL)
- {
- return -1; /* (error message is set) */
- }
-
- points = aggr_points;
- }
- }
-
- if (points == NULL)
- {
- /*
- * The list will be cleared including the points since 'merge_as'
- * is still not NULL. (error message is set)
- */
- return -1;
- }
-
- if (query->factor)
- {
- siridb_points_ts_correction(points, (double) query->factor);
- }
-
- if (siridb_points_pack(points, query->packer))
- {
- sprintf(query->err_msg, "Memory allocation error.");
- siridb_points_free(points);
- return -1;
- }
-
- siridb_points_free(points);
-
- return 0;
-}
-
-/*
- * Returns 0 when successful and -1 in case of an error.
- * (a SIGNAL is raised in case of an error)
- */
-static int items_select_other(
- const char * name,
- size_t len,
- siridb_points_t * points,
- uv_async_t * handle)
-{
- siridb_query_t * query = (siridb_query_t *) handle->data;
-
- return -(qp_add_raw_term(
- query->packer, (const unsigned char *) name, len) ||
- siridb_points_raw_pack(points, query->packer));
-}
-
-/*
- * Returns 0 when successful and -1 in case of an error.
- * (a SIGNAL is raised in case of an error)
- */
-static int items_select_other_merge(
- const char * name,
- size_t len,
- slist_t * plist,
- uv_async_t * handle)
-{
- size_t i;
- siridb_query_t * query = (siridb_query_t *) handle->data;
- int rc = qp_add_raw_term(
- query->packer, (const unsigned char *) name, len) ||
- qp_add_type(query->packer, QP_ARRAY_OPEN);
-
- for (i = 0; !rc && i < plist->len; i++)
- {
- rc = siridb_points_raw_pack(
- (siridb_points_t * ) plist->data[i],
- query->packer);
- }
-
- return -(rc || qp_add_type(query->packer, QP_ARRAY_CLOSE));
-}
-
-static void on_select_unpack_points(
- qp_unpacker_t * unpacker,
- query_select_t * q_select,
- qp_obj_t * qp_name,
- qp_obj_t * qp_tp,
- qp_obj_t * qp_len,
- qp_obj_t * qp_points,
- uint32_t select_points_limit)
-{
- siridb_points_t * points;
-
- while ( q_select->n <= select_points_limit &&
- qp_is_raw(qp_next(unpacker, qp_name)) &&
- qp_is_raw_term(qp_name) &&
- qp_is_array(qp_next(unpacker, NULL)) &&
- qp_is_int(qp_next(unpacker, qp_tp)) &&
- qp_is_int(qp_next(unpacker, qp_len)) &&
- qp_is_raw(qp_next(unpacker, qp_points)))
- {
- points = siridb_points_new(qp_len->via.int64, qp_tp->via.int64);
- if (points != NULL)
- {
- if (points->tp == TP_STRING)
- {
- if (qp_len->via.int64 < POINTS_ZIP_THRESHOLD)
- {
- siridb_points_unzip_string_raw(
- points,
- qp_points->via.raw,
- qp_len->via.int64);
- }
- else
- {
- siridb_points_unzip_string(
- points,
- qp_points->via.raw,
- qp_len->via.int64,
- NULL, NULL, 0);
- }
- }
- else
- {
- points->len = qp_len->via.int64;
- memcpy(points->data, qp_points->via.raw, qp_points->len);
- }
-
- if (ct_add(q_select->result, (char *) qp_name->via.raw, points))
- {
- siridb_points_free(points);
- }
- else
- {
- q_select->n += points->len;
- }
- }
-
- qp_next(unpacker, NULL); /* QP_ARRAY_CLOSE */
- }
-}
-
-static void on_select_unpack_merged_points(
- qp_unpacker_t * unpacker,
- query_select_t * q_select,
- qp_obj_t * qp_name,
- qp_obj_t * qp_tp,
- qp_obj_t * qp_len,
- qp_obj_t * qp_points,
- uint32_t select_points_limit)
-{
- siridb_points_t * points;
-
- while ( qp_is_raw(qp_next(unpacker, qp_name)) &&
-#if DEBUG
- qp_is_raw_term(qp_name) &&
-#endif
- qp_is_array(qp_next(unpacker, NULL)))
-
- {
- slist_t ** plist = (slist_t **) ct_getaddr(
- q_select->result,
- (const char *) qp_name->via.raw);
-
- while ( q_select->n <= select_points_limit &&
- qp_is_array(qp_next(unpacker, NULL)) &&
- qp_is_int(qp_next(unpacker, qp_tp)) &&
- qp_is_int(qp_next(unpacker, qp_len)) &&
- qp_is_raw(qp_next(unpacker, qp_points)))
- {
-
- points = siridb_points_new(qp_len->via.int64, qp_tp->via.int64);
-
- if (points != NULL)
- {
- if (points->tp == TP_STRING)
- {
- if (qp_len->via.int64 < POINTS_ZIP_THRESHOLD)
- {
- siridb_points_unzip_string_raw(
- points,
- qp_points->via.raw,
- qp_len->via.int64);
- }
- else
- {
- siridb_points_unzip_string(
- points,
- qp_points->via.raw,
- qp_len->via.int64,
- NULL, NULL, 0);
- }
- }
- else
- {
- points->len = qp_len->via.int64;
- memcpy(points->data, qp_points->via.raw, qp_points->len);
- }
-
- if (slist_append_safe(plist, points))
- {
- siridb_points_free(points);
- }
- else
- {
- q_select->n += points->len;
- }
- }
-
- qp_next(unpacker, NULL); /* QP_ARRAY_CLOSE */
- }
- }
-}
-
-static int values_list_groups(siridb_group_t * group, uv_async_t * handle)
-{
- siridb_query_t * query = (siridb_query_t *) handle->data;
- cexpr_t * where_expr = ((query_list_t *) query->data)->where_expr;
- cexpr_cb_t cb = (cexpr_cb_t) siridb_group_cexpr_cb;
- slist_t * props = ((query_list_t *) query->data)->props;
-
- if (where_expr == NULL || cexpr_run(where_expr, cb, group))
- {
- size_t i;
- qp_add_type(query->packer, QP_ARRAY_OPEN);
-
- for (i = 0; i < props->len; i++)
- {
- siridb_group_prop(
- group,
- query->packer,
- *((uint32_t *) props->data[i]));
- }
-
- qp_add_type(query->packer, QP_ARRAY_CLOSE);
-
- return 1;
- }
-
- return 0;
-}
-
-static int values_count_groups(siridb_group_t * group, uv_async_t * handle)
-{
- siridb_query_t * query = (siridb_query_t *) handle->data;
-
- return cexpr_run(
- ((query_list_t *) query->data)->where_expr,
- (cexpr_cb_t) siridb_group_cexpr_cb,
- group);
-}
-
-static void finish_list_groups(uv_async_t * handle)
-{
- siridb_query_t * query = (siridb_query_t *) handle->data;
- query_list_t * q_list = (query_list_t *) query->data;
- CLIENT_SIRIDB(query->client, siridb)
-
- if (q_list->props == NULL)
- {
- q_list->props = slist_new(1);
- if (q_list->props == NULL)
- {
- MEM_ERR_RET
- }
- slist_append(q_list->props, &GID_K_NAME);
- qp_add_raw(query->packer, (const unsigned char *) "name", 4);
- }
-
- qp_add_type(query->packer, QP_ARRAY_CLOSE);
-
- qp_add_raw(query->packer, (const unsigned char *) "groups", 6);
- qp_add_type(query->packer, QP_ARRAY_OPEN);
-
- ct_valuesn(
- siridb->groups->groups,
- &q_list->limit,
- (ct_val_cb) values_list_groups,
- handle);
-
- qp_add_type(query->packer, QP_ARRAY_CLOSE);
-
- SIRIPARSER_ASYNC_NEXT_NODE
-}
-
-static void finish_count_groups(uv_async_t * handle)
-{
- siridb_query_t * query = (siridb_query_t *) handle->data;
- query_count_t * q_count = (query_count_t *) query->data;
- CLIENT_SIRIDB(query->client, siridb)
-
- /* Note: ct_values(..values_count_groups..) can only result in a positive
- * value.
- */
- size_t n = (q_count->where_expr == NULL) ?
- siridb->groups->groups->len :
- (size_t) ct_values(
- siridb->groups->groups,
- (ct_val_cb) values_count_groups,
- handle);
-
- qp_add_raw(query->packer, (const unsigned char *) "groups", 6);
-
- qp_add_int64(query->packer, n);
-
- SIRIPARSER_ASYNC_NEXT_NODE
-}
+++ /dev/null
-/*
- * queries.c - Querie helpers for listener
- *
- * author : Jeroen van der Heijden
- * email : jeroen@transceptor.technology
- * copyright : 2016, Transceptor Technology
- *
- * changes
- * - initial version, 03-05-2016
- *
- */
-#include <assert.h>
-#include <logger/logger.h>
-#include <siri/db/aggregate.h>
-#include <siri/db/query.h>
-#include <siri/db/shard.h>
-#include <siri/parser/queries.h>
-#include <stddef.h>
-#include <stdlib.h>
-
-#define DEFAULT_LIST_LIMIT 1000
-
-#define QUERIES_NEW(q) \
-q->flags = 0; \
-q->series_map = NULL; \
-q->series_tmp = NULL; \
-q->slist = NULL; \
-q->slist_index = 0; \
-q->pmap = NULL; \
-q->update_cb = NULL; \
-q->where_expr = NULL; \
-q->regex = NULL; \
-q->match_data = NULL;
-
-
-#define QUERIES_FREE(q, handle) \
-if (q->series_map != NULL) \
-{ \
- imap_free( \
- q->series_map, \
- (imap_free_cb) &siridb__series_decref); \
-} \
-if (q->series_tmp != NULL) \
-{ \
- imap_free( \
- q->series_tmp, \
- (imap_free_cb) &siridb__series_decref); \
-} \
-if (q->slist != NULL) \
-{ \
- siridb_series_t * series; \
- for (; q->slist_index < q->slist->len; q->slist_index++) \
- { \
- series = (siridb_series_t *) q->slist->data[q->slist_index]; \
- siridb_series_decref(series); \
- } \
- slist_free(q->slist); \
-} \
-if (q->where_expr != NULL) \
-{ \
- cexpr_free(q->where_expr); \
-} \
-if (q->pmap != NULL) \
-{ \
- imap_free(q->pmap, NULL); \
-} \
-pcre2_code_free(q->regex); \
-pcre2_match_data_free(q->match_data); \
-free(q); \
-siridb_query_free(handle);
-
-static void QUERIES_free_merge_result(slist_t * plist);
-
-query_select_t * query_select_new(void)
-{
- query_select_t * q_select =
- (query_select_t *) malloc(sizeof(query_select_t));
-
- if (q_select == NULL)
- {
- return NULL;
- }
- QUERIES_NEW(q_select)
-
- q_select->tp = QUERIES_SELECT;
- q_select->start_ts = NULL;
- q_select->end_ts = NULL;
- q_select->presuf = NULL;
- q_select->merge_as = NULL;
- q_select->n = 0;
- q_select->nselects = 1; /* we have at least one select function */
- q_select->points_map = NULL;
- q_select->alist = NULL;
- q_select->mlist = NULL;
- q_select->result = ct_new();
-
- if (q_select->result == NULL)
- {
- free(q_select);
- return NULL;
- }
-
- return q_select;
-}
-
-query_alter_t * query_alter_new(void)
-{
- query_alter_t * q_alter =
- (query_alter_t *) malloc(sizeof(query_alter_t));
-
- if (q_alter == NULL)
- {
- return NULL;
- }
-
- QUERIES_NEW(q_alter)
-
- q_alter->tp = QUERIES_ALTER;
- q_alter->alter_tp = QUERY_ALTER_NONE;
- q_alter->via.dummy = NULL;
- q_alter->n = 0;
-
- return q_alter;
-}
-
-query_count_t * query_count_new(void)
-{
- query_count_t * q_count =
- (query_count_t *) malloc(sizeof(query_count_t));
-
- if (q_count == NULL)
- {
- return NULL;
- }
-
- QUERIES_NEW(q_count)
-
- q_count->tp = QUERIES_COUNT;
- q_count->n = 0;
-
- return q_count;
-}
-
-query_drop_t * query_drop_new(void)
-{
- query_drop_t * q_drop =
- (query_drop_t *) malloc(sizeof(query_drop_t));
-
- if (q_drop == NULL)
- {
- return NULL;
- }
-
- QUERIES_NEW(q_drop)
-
- q_drop->tp = QUERIES_DROP;
- q_drop->n = 0;
- q_drop->flags = 0;
- q_drop->shards_list = NULL;
-
- return q_drop;
-}
-
-query_list_t * query_list_new(void)
-{
- query_list_t * q_list =
- (query_list_t *) malloc(sizeof(query_list_t));
-
- if (q_list == NULL)
- {
- return NULL;
- }
-
- QUERIES_NEW(q_list)
-
- q_list->tp = QUERIES_LIST;
- q_list->props = NULL;
- q_list->limit = DEFAULT_LIST_LIMIT;
-
- return q_list;
-}
-
-void query_alter_free(uv_handle_t * handle)
-{
- query_alter_t * q_alter =
- (query_alter_t *) ((siridb_query_t *) handle->data)->data;
-
- switch (q_alter->alter_tp)
- {
- case QUERY_ALTER_NONE:
- case QUERY_ALTER_DATABASE:
- case QUERY_ALTER_SERVERS:
- break;
- case QUERY_ALTER_GROUP:
- siridb_group_decref(q_alter->via.group);
- break;
- case QUERY_ALTER_SERVER:
- siridb_server_decref(q_alter->via.server);
- break;
- case QUERY_ALTER_USER:
- siridb_user_decref(q_alter->via.user);
- break;
- default:
- assert(0);
- }
-
- QUERIES_FREE(q_alter, handle)
-}
-
-void query_count_free(uv_handle_t * handle)
-{
- query_count_t * q_count =
- (query_count_t *) ((siridb_query_t *) handle->data)->data;
-
- QUERIES_FREE(q_count, handle)
-}
-
-void query_drop_free(uv_handle_t * handle)
-{
- query_drop_t * q_drop =
- (query_drop_t *) ((siridb_query_t *) handle->data)->data;
-
- if (q_drop->shards_list != NULL)
- {
- siridb_shard_t * shard;
- while (q_drop->shards_list->len)
- {
- shard = (siridb_shard_t *) slist_pop(q_drop->shards_list);
- siridb_shard_decref(shard);
- }
-
- slist_free(q_drop->shards_list);
- }
-
- QUERIES_FREE(q_drop, handle)
-}
-
-void query_list_free(uv_handle_t * handle)
-{
- query_list_t * q_list =
- (query_list_t *) ((siridb_query_t *) handle->data)->data;
-
- if (q_list->props != NULL)
- {
- slist_free(q_list->props);
- }
-
- QUERIES_FREE(q_list, handle)
-}
-
-void query_select_free(uv_handle_t * handle)
-{
- query_select_t * q_select =
- (query_select_t *) ((siridb_query_t *) handle->data)->data;
-
- siridb_presuf_free(q_select->presuf);
-
- if (q_select->points_map != NULL)
- {
- imap_free(q_select->points_map, (imap_free_cb) &siridb_points_free);
- }
-
- if (q_select->result != NULL)
- {
- if (q_select->merge_as == NULL)
- {
- ct_free(q_select->result, (ct_free_cb) &siridb_points_free);
- }
- else
- {
- ct_free(q_select->result, (ct_free_cb) &QUERIES_free_merge_result);
- }
- }
-
- free(q_select->merge_as);
-
- if (q_select->alist != NULL)
- {
- siridb_aggregate_list_free(q_select->alist);
- }
-
- if (q_select->mlist != NULL)
- {
- siridb_aggregate_list_free(q_select->mlist);
- }
-
- QUERIES_FREE(q_select, handle)
-}
-
-void query_help_free(uv_handle_t * handle)
-{
- /* used as char to hold a string */
- free(((siridb_query_t *) handle->data)->data);
-
- /* normal call-back */
- siridb_query_free(handle);
-}
-
-static void QUERIES_free_merge_result(slist_t * plist)
-{
- size_t i;
- for (i = 0; i < plist->len; i ++)
- {
- siridb_points_free(plist->data[i]);
- }
- free(plist);
-}
#include <siri/db/server.h>
#include <siri/db/servers.h>
#include <siri/db/users.h>
+#include <siri/db/listener.h>
#include <siri/err.h>
#include <siri/help/help.h>
#include <siri/net/bserver.h>
#include <siri/net/clserver.h>
#include <siri/net/pipe.h>
-#include <siri/net/socket.h>
-#include <siri/parser/listener.h>
+#include <siri/net/stream.h>
#include <siri/siri.h>
#include <siri/version.h>
#include <stddef.h>
.accounts=NULL,
.dbname_regex=NULL,
.dbname_match_data=NULL,
- .socket=NULL};
+ .client=NULL};
void siri_setup_logger(void)
{
clock_gettime(CLOCK_MONOTONIC, &start);
/* initialize listener (set enter and exit functions) */
- siriparser_init_listener();
+ siridb_init_listener();
/* initialize props (set props functions) */
siridb_init_props();
break;
case UV_TCP:
- /* This can be a TCP server with data set to NULL or a SiriDB socket
- * which should be destroyed.
- */
- if (handle->data == NULL)
- {
- uv_close(handle, NULL);
- }
- else
- {
- sirinet_socket_decref(handle);
- }
- break;
-
case UV_NAMED_PIPE:
- /* This can be a pipe server with data set to NULL or a SiriDB pipe
- * which should be destroyed.
- */
if (handle->data == NULL)
{
uv_close(handle, NULL);
}
else
{
- sirinet_pipe_decref(handle);
+ sirinet_stream_decref((sirinet_stream_t *) handle->data);
}
break;